##// END OF EJS Templates
front-end: Use codemirror from node_modules and stop bundling it
Mads Kiilerich -
r7386:bf514091 default
parent child Browse files
Show More
@@ -24,6 +24,7 b' syntax: regexp'
24 ^kallithea/front-end/node_modules$
24 ^kallithea/front-end/node_modules$
25 ^kallithea/front-end/package-lock\.json$
25 ^kallithea/front-end/package-lock\.json$
26 ^kallithea/front-end/tmp$
26 ^kallithea/front-end/tmp$
27 ^kallithea/public/codemirror$
27 ^kallithea/public/css/select2-spinner\.gif$
28 ^kallithea/public/css/select2-spinner\.gif$
28 ^kallithea/public/css/select2\.png$
29 ^kallithea/public/css/select2\.png$
29 ^kallithea/public/css/select2x2\.png$
30 ^kallithea/public/css/select2x2\.png$
@@ -54,7 +54,7 b" using the ''kallithea-cli front-end-buil"
54 Codemirror
54 Codemirror
55 ----------
55 ----------
56
56
57 Kallithea incorporates parts of the Javascript system called
57 Kallithea uses the Javascript system called
58 [Codemirror](http://codemirror.net/), version 4.7.0, which is primarily:
58 [Codemirror](http://codemirror.net/), version 4.7.0, which is primarily:
59
59
60 Copyright &copy; 2013-2014 by Marijn Haverbeke <marijnh@gmail.com>
60 Copyright &copy; 2013-2014 by Marijn Haverbeke <marijnh@gmail.com>
@@ -63,10 +63,10 b' and licensed under the MIT-permissive li'
63 [included in this distribution](MIT-Permissive-License.txt).
63 [included in this distribution](MIT-Permissive-License.txt).
64
64
65 Additional files from upstream Codemirror are copyrighted by various authors
65 Additional files from upstream Codemirror are copyrighted by various authors
66 and licensed under other permissive licenses. The sub-directories under
66 and licensed under other permissive licenses.
67 [.../public/codemirror](kallithea/public/codemirror) include the copyright and
67
68 license notice and information as they appeared in Codemirror's upstream
68 It is not distributed with Kallithea, but will be downloaded
69 release.
69 using the ''kallithea-cli front-end-build'' command.
70
70
71
71
72
72
@@ -82,6 +82,11 b' def front_end_build(install_deps, genera'
82 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'select2', 'select2x2.png'), os.path.join(public_dir, 'css', 'select2x2.png'))
82 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'select2', 'select2x2.png'), os.path.join(public_dir, 'css', 'select2x2.png'))
83 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'select2', 'select2-spinner.gif'), os.path.join(public_dir, 'css', 'select2-spinner.gif'))
83 shutil.copy(os.path.join(front_end_dir, 'node_modules', 'select2', 'select2-spinner.gif'), os.path.join(public_dir, 'css', 'select2-spinner.gif'))
84
84
85 click.echo("Preparing CodeMirror JS")
86 if os.path.isdir(os.path.join(public_dir, 'codemirror')):
87 shutil.rmtree(os.path.join(public_dir, 'codemirror'))
88 shutil.copytree(os.path.join(front_end_dir, 'node_modules', 'codemirror'), os.path.join(public_dir, 'codemirror'))
89
85 click.echo("Generating LICENSES.txt")
90 click.echo("Generating LICENSES.txt")
86 check_licensing_json_path = os.path.join(tmp_dir, 'licensing.json')
91 check_licensing_json_path = os.path.join(tmp_dir, 'licensing.json')
87 licensing_txt_path = os.path.join(public_dir, 'LICENSES.txt')
92 licensing_txt_path = os.path.join(public_dir, 'LICENSES.txt')
@@ -3,6 +3,7 b''
3 "private": true,
3 "private": true,
4 "dependencies": {
4 "dependencies": {
5 "bootstrap": "3.3.7",
5 "bootstrap": "3.3.7",
6 "codemirror": "4.7",
6 "datatables.net": "1.10.13",
7 "datatables.net": "1.10.13",
7 "datatables.net-bs": "1.10.13",
8 "datatables.net-bs": "1.10.13",
8 "jquery": "1.12.3",
9 "jquery": "1.12.3",
@@ -2,7 +2,7 b''
2
2
3 # Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
3 # Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
4
4
5 files=`hg mani | egrep -v '/codemirror/|/fontello/|/email_templates/|(/lockfiles.py|^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history|yui.2.9)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
5 files=`hg mani | egrep -v '/fontello/|/email_templates/|(/lockfiles.py|^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history|yui.2.9)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
6
6
7 sed -i "s/`printf '\r'`//g" $files
7 sed -i "s/`printf '\r'`//g" $files
8 sed -i -e "s,`printf '\t'`, ,g" $files
8 sed -i -e "s,`printf '\t'`, ,g" $files
@@ -1,19 +0,0 b''
1 Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE.
@@ -1,309 +0,0 b''
1 /* BASICS */
2
3 .CodeMirror {
4 /* Set height, width, borders, and global font properties here */
5 font-family: monospace;
6 height: 300px;
7 }
8 .CodeMirror-scroll {
9 /* Set scrolling behaviour here */
10 overflow: auto;
11 }
12
13 /* PADDING */
14
15 .CodeMirror-lines {
16 padding: 4px 0; /* Vertical padding around content */
17 }
18 .CodeMirror pre {
19 padding: 0 4px; /* Horizontal padding of content */
20 }
21
22 .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
23 background-color: white; /* The little square between H and V scrollbars */
24 }
25
26 /* GUTTER */
27
28 .CodeMirror-gutters {
29 border-right: 1px solid #ddd;
30 background-color: #f7f7f7;
31 white-space: nowrap;
32 }
33 .CodeMirror-linenumbers {}
34 .CodeMirror-linenumber {
35 padding: 0 3px 0 5px;
36 min-width: 20px;
37 text-align: right;
38 color: #999;
39 -moz-box-sizing: content-box;
40 box-sizing: content-box;
41 }
42
43 .CodeMirror-guttermarker { color: black; }
44 .CodeMirror-guttermarker-subtle { color: #999; }
45
46 /* CURSOR */
47
48 .CodeMirror div.CodeMirror-cursor {
49 border-left: 1px solid black;
50 }
51 /* Shown when moving in bi-directional text */
52 .CodeMirror div.CodeMirror-secondarycursor {
53 border-left: 1px solid silver;
54 }
55 .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
56 width: auto;
57 border: 0;
58 background: #7e7;
59 }
60 .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursors {
61 z-index: 1;
62 }
63
64 .cm-animate-fat-cursor {
65 width: auto;
66 border: 0;
67 -webkit-animation: blink 1.06s steps(1) infinite;
68 -moz-animation: blink 1.06s steps(1) infinite;
69 animation: blink 1.06s steps(1) infinite;
70 }
71 @-moz-keyframes blink {
72 0% { background: #7e7; }
73 50% { background: none; }
74 100% { background: #7e7; }
75 }
76 @-webkit-keyframes blink {
77 0% { background: #7e7; }
78 50% { background: none; }
79 100% { background: #7e7; }
80 }
81 @keyframes blink {
82 0% { background: #7e7; }
83 50% { background: none; }
84 100% { background: #7e7; }
85 }
86
87 /* Can style cursor different in overwrite (non-insert) mode */
88 div.CodeMirror-overwrite div.CodeMirror-cursor {}
89
90 .cm-tab { display: inline-block; text-decoration: inherit; }
91
92 .CodeMirror-ruler {
93 border-left: 1px solid #ccc;
94 position: absolute;
95 }
96
97 /* DEFAULT THEME */
98
99 .cm-s-default .cm-keyword {color: #708;}
100 .cm-s-default .cm-atom {color: #219;}
101 .cm-s-default .cm-number {color: #164;}
102 .cm-s-default .cm-def {color: #00f;}
103 .cm-s-default .cm-variable,
104 .cm-s-default .cm-punctuation,
105 .cm-s-default .cm-property,
106 .cm-s-default .cm-operator {}
107 .cm-s-default .cm-variable-2 {color: #05a;}
108 .cm-s-default .cm-variable-3 {color: #085;}
109 .cm-s-default .cm-comment {color: #a50;}
110 .cm-s-default .cm-string {color: #a11;}
111 .cm-s-default .cm-string-2 {color: #f50;}
112 .cm-s-default .cm-meta {color: #555;}
113 .cm-s-default .cm-qualifier {color: #555;}
114 .cm-s-default .cm-builtin {color: #30a;}
115 .cm-s-default .cm-bracket {color: #997;}
116 .cm-s-default .cm-tag {color: #170;}
117 .cm-s-default .cm-attribute {color: #00c;}
118 .cm-s-default .cm-header {color: blue;}
119 .cm-s-default .cm-quote {color: #090;}
120 .cm-s-default .cm-hr {color: #999;}
121 .cm-s-default .cm-link {color: #00c;}
122
123 .cm-negative {color: #d44;}
124 .cm-positive {color: #292;}
125 .cm-header, .cm-strong {font-weight: bold;}
126 .cm-em {font-style: italic;}
127 .cm-link {text-decoration: underline;}
128
129 .cm-s-default .cm-error {color: #f00;}
130 .cm-invalidchar {color: #f00;}
131
132 /* Default styles for common addons */
133
134 div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
135 div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
136 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
137 .CodeMirror-activeline-background {background: #e8f2ff;}
138
139 /* STOP */
140
141 /* The rest of this file contains styles related to the mechanics of
142 the editor. You probably shouldn't touch them. */
143
144 .CodeMirror {
145 line-height: 1;
146 position: relative;
147 overflow: hidden;
148 background: white;
149 color: black;
150 }
151
152 .CodeMirror-scroll {
153 /* 30px is the magic margin used to hide the element's real scrollbars */
154 /* See overflow: hidden in .CodeMirror */
155 margin-bottom: -30px; margin-right: -30px;
156 padding-bottom: 30px;
157 height: 100%;
158 outline: none; /* Prevent dragging from highlighting the element */
159 position: relative;
160 -moz-box-sizing: content-box;
161 box-sizing: content-box;
162 }
163 .CodeMirror-sizer {
164 position: relative;
165 border-right: 30px solid transparent;
166 -moz-box-sizing: content-box;
167 box-sizing: content-box;
168 }
169
170 /* The fake, visible scrollbars. Used to force redraw during scrolling
171 before actuall scrolling happens, thus preventing shaking and
172 flickering artifacts. */
173 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
174 position: absolute;
175 z-index: 6;
176 display: none;
177 }
178 .CodeMirror-vscrollbar {
179 right: 0; top: 0;
180 overflow-x: hidden;
181 overflow-y: scroll;
182 }
183 .CodeMirror-hscrollbar {
184 bottom: 0; left: 0;
185 overflow-y: hidden;
186 overflow-x: scroll;
187 }
188 .CodeMirror-scrollbar-filler {
189 right: 0; bottom: 0;
190 }
191 .CodeMirror-gutter-filler {
192 left: 0; bottom: 0;
193 }
194
195 .CodeMirror-gutters {
196 position: absolute; left: 0; top: 0;
197 padding-bottom: 30px;
198 z-index: 3;
199 }
200 .CodeMirror-gutter {
201 white-space: normal;
202 height: 100%;
203 -moz-box-sizing: content-box;
204 box-sizing: content-box;
205 padding-bottom: 30px;
206 margin-bottom: -32px;
207 display: inline-block;
208 /* Hack to make IE7 behave */
209 *zoom:1;
210 *display:inline;
211 }
212 .CodeMirror-gutter-elt {
213 position: absolute;
214 cursor: default;
215 z-index: 4;
216 }
217
218 .CodeMirror-lines {
219 cursor: text;
220 min-height: 1px; /* prevents collapsing before first draw */
221 }
222 .CodeMirror pre {
223 /* Reset some styles that the rest of the page might have set */
224 -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
225 border-width: 0;
226 background: transparent;
227 font-family: inherit;
228 font-size: inherit;
229 margin: 0;
230 white-space: pre;
231 word-wrap: normal;
232 line-height: inherit;
233 color: inherit;
234 z-index: 2;
235 position: relative;
236 overflow: visible;
237 }
238 .CodeMirror-wrap pre {
239 word-wrap: break-word;
240 white-space: pre-wrap;
241 word-break: normal;
242 }
243
244 .CodeMirror-linebackground {
245 position: absolute;
246 left: 0; right: 0; top: 0; bottom: 0;
247 z-index: 0;
248 }
249
250 .CodeMirror-linewidget {
251 position: relative;
252 z-index: 2;
253 overflow: auto;
254 }
255
256 .CodeMirror-widget {}
257
258 .CodeMirror-wrap .CodeMirror-scroll {
259 overflow-x: hidden;
260 }
261
262 .CodeMirror-measure {
263 position: absolute;
264 width: 100%;
265 height: 0;
266 overflow: hidden;
267 visibility: hidden;
268 }
269 .CodeMirror-measure pre { position: static; }
270
271 .CodeMirror div.CodeMirror-cursor {
272 position: absolute;
273 border-right: none;
274 width: 0;
275 }
276
277 div.CodeMirror-cursors {
278 visibility: hidden;
279 position: relative;
280 z-index: 3;
281 }
282 .CodeMirror-focused div.CodeMirror-cursors {
283 visibility: visible;
284 }
285
286 .CodeMirror-selected { background: #d9d9d9; }
287 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
288 .CodeMirror-crosshair { cursor: crosshair; }
289
290 .cm-searching {
291 background: #ffa;
292 background: rgba(255, 255, 0, .4);
293 }
294
295 /* IE7 hack to prevent it from returning funny offsetTops on the spans */
296 .CodeMirror span { *vertical-align: text-bottom; }
297
298 /* Used to force a border model for a node */
299 .cm-force-border { padding-right: .1px; }
300
301 @media print {
302 /* Hide the cursor when printing */
303 .CodeMirror div.CodeMirror-cursors {
304 visibility: hidden;
305 }
306 }
307
308 /* Help users use markselection to safely style text background */
309 span.CodeMirror-selectedtext { background: none; }
This diff has been collapsed as it changes many lines, (7830 lines changed) Show them Hide them
@@ -1,7830 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // This is CodeMirror (http://codemirror.net), a code editor
5 // implemented in JavaScript on top of the browser's DOM.
6 //
7 // You can find some technical background for some of the code below
8 // at http://marijnhaverbeke.nl/blog/#cm-internals .
9
10 (function(mod) {
11 if (typeof exports == "object" && typeof module == "object") // CommonJS
12 module.exports = mod();
13 else if (typeof define == "function" && define.amd) // AMD
14 return define([], mod);
15 else // Plain browser env
16 this.CodeMirror = mod();
17 })(function() {
18 "use strict";
19
20 // BROWSER SNIFFING
21
22 // Kludges for bugs and behavior differences that can't be feature
23 // detected are enabled based on userAgent etc sniffing.
24
25 var gecko = /gecko\/\d/i.test(navigator.userAgent);
26 // ie_uptoN means Internet Explorer version N or lower
27 var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
28 var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
29 var ie = ie_upto10 || ie_11up;
30 var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
31 var webkit = /WebKit\//.test(navigator.userAgent);
32 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
33 var chrome = /Chrome\//.test(navigator.userAgent);
34 var presto = /Opera\//.test(navigator.userAgent);
35 var safari = /Apple Computer/.test(navigator.vendor);
36 var khtml = /KHTML\//.test(navigator.userAgent);
37 var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
38 var phantom = /PhantomJS/.test(navigator.userAgent);
39
40 var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
41 // This is woefully incomplete. Suggestions for alternative methods welcome.
42 var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
43 var mac = ios || /Mac/.test(navigator.platform);
44 var windows = /win/i.test(navigator.platform);
45
46 var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
47 if (presto_version) presto_version = Number(presto_version[1]);
48 if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
49 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
50 var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
51 var captureRightClick = gecko || (ie && ie_version >= 9);
52
53 // Optimize some code when these features are not used.
54 var sawReadOnlySpans = false, sawCollapsedSpans = false;
55
56 // EDITOR CONSTRUCTOR
57
58 // A CodeMirror instance represents an editor. This is the object
59 // that user code is usually dealing with.
60
61 function CodeMirror(place, options) {
62 if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
63
64 this.options = options = options ? copyObj(options) : {};
65 // Determine effective options based on given values and defaults.
66 copyObj(defaults, options, false);
67 setGuttersForLineNumbers(options);
68
69 var doc = options.value;
70 if (typeof doc == "string") doc = new Doc(doc, options.mode);
71 this.doc = doc;
72
73 var display = this.display = new Display(place, doc);
74 display.wrapper.CodeMirror = this;
75 updateGutters(this);
76 themeChanged(this);
77 if (options.lineWrapping)
78 this.display.wrapper.className += " CodeMirror-wrap";
79 if (options.autofocus && !mobile) focusInput(this);
80
81 this.state = {
82 keyMaps: [], // stores maps added by addKeyMap
83 overlays: [], // highlighting overlays, as added by addOverlay
84 modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
85 overwrite: false, focused: false,
86 suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
87 pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
88 draggingText: false,
89 highlight: new Delayed() // stores highlight worker timeout
90 };
91
92 // Override magic textarea content restore that IE sometimes does
93 // on our hidden textarea on reload
94 if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);
95
96 registerEventHandlers(this);
97 ensureGlobalHandlers();
98
99 startOperation(this);
100 this.curOp.forceUpdate = true;
101 attachDoc(this, doc);
102
103 if ((options.autofocus && !mobile) || activeElt() == display.input)
104 setTimeout(bind(onFocus, this), 20);
105 else
106 onBlur(this);
107
108 for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
109 optionHandlers[opt](this, options[opt], Init);
110 maybeUpdateLineNumberWidth(this);
111 for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
112 endOperation(this);
113 }
114
115 // DISPLAY CONSTRUCTOR
116
117 // The display handles the DOM integration, both for input reading
118 // and content drawing. It holds references to DOM nodes and
119 // display-related state.
120
121 function Display(place, doc) {
122 var d = this;
123
124 // The semihidden textarea that is focused when the editor is
125 // focused, and receives input.
126 var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
127 // The textarea is kept positioned near the cursor to prevent the
128 // fact that it'll be scrolled into view on input from scrolling
129 // our fake cursor out of view. On webkit, when wrap=off, paste is
130 // very slow. So make the area wide instead.
131 if (webkit) input.style.width = "1000px";
132 else input.setAttribute("wrap", "off");
133 // If border: 0; -- iOS fails to open keyboard (issue #1287)
134 if (ios) input.style.border = "1px solid black";
135 input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
136
137 // Wraps and hides input textarea
138 d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
139 // The fake scrollbar elements.
140 d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
141 d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
142 // Covers bottom-right square when both scrollbars are present.
143 d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
144 // Covers bottom of gutter when coverGutterNextToScrollbar is on
145 // and h scrollbar is present.
146 d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
147 // Will contain the actual code, positioned to cover the viewport.
148 d.lineDiv = elt("div", null, "CodeMirror-code");
149 // Elements are added to these to represent selection and cursors.
150 d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
151 d.cursorDiv = elt("div", null, "CodeMirror-cursors");
152 // A visibility: hidden element used to find the size of things.
153 d.measure = elt("div", null, "CodeMirror-measure");
154 // When lines outside of the viewport are measured, they are drawn in this.
155 d.lineMeasure = elt("div", null, "CodeMirror-measure");
156 // Wraps everything that needs to exist inside the vertically-padded coordinate system
157 d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
158 null, "position: relative; outline: none");
159 // Moved around its parent to cover visible view.
160 d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
161 // Set to the height of the document, allowing scrolling.
162 d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
163 // Behavior of elts with overflow: auto and padding is
164 // inconsistent across browsers. This is used to ensure the
165 // scrollable area is big enough.
166 d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
167 // Will contain the gutters, if any.
168 d.gutters = elt("div", null, "CodeMirror-gutters");
169 d.lineGutter = null;
170 // Actual scrollable element.
171 d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
172 d.scroller.setAttribute("tabIndex", "-1");
173 // The element in which the editor lives.
174 d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
175 d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
176
177 // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
178 if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
179 // Needed to hide big blue blinking cursor on Mobile Safari
180 if (ios) input.style.width = "0px";
181 if (!webkit) d.scroller.draggable = true;
182 // Needed to handle Tab key in KHTML
183 if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
184 // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
185 if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
186
187 if (place.appendChild) place.appendChild(d.wrapper);
188 else place(d.wrapper);
189
190 // Current rendered range (may be bigger than the view window).
191 d.viewFrom = d.viewTo = doc.first;
192 // Information about the rendered lines.
193 d.view = [];
194 // Holds info about a single rendered line when it was rendered
195 // for measurement, while not in view.
196 d.externalMeasured = null;
197 // Empty space (in pixels) above the view
198 d.viewOffset = 0;
199 d.lastSizeC = 0;
200 d.updateLineNumbers = null;
201
202 // Used to only resize the line number gutter when necessary (when
203 // the amount of lines crosses a boundary that makes its width change)
204 d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
205 // See readInput and resetInput
206 d.prevInput = "";
207 // Set to true when a non-horizontal-scrolling line widget is
208 // added. As an optimization, line widget aligning is skipped when
209 // this is false.
210 d.alignWidgets = false;
211 // Flag that indicates whether we expect input to appear real soon
212 // now (after some event like 'keypress' or 'input') and are
213 // polling intensively.
214 d.pollingFast = false;
215 // Self-resetting timeout for the poller
216 d.poll = new Delayed();
217
218 d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
219
220 // Tracks when resetInput has punted to just putting a short
221 // string into the textarea instead of the full selection.
222 d.inaccurateSelection = false;
223
224 // Tracks the maximum line length so that the horizontal scrollbar
225 // can be kept static when scrolling.
226 d.maxLine = null;
227 d.maxLineLength = 0;
228 d.maxLineChanged = false;
229
230 // Used for measuring wheel scrolling granularity
231 d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
232
233 // True when shift is held down.
234 d.shift = false;
235
236 // Used to track whether anything happened since the context menu
237 // was opened.
238 d.selForContextMenu = null;
239 }
240
241 // STATE UPDATES
242
243 // Used to get the editor into a consistent state again when options change.
244
245 function loadMode(cm) {
246 cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
247 resetModeState(cm);
248 }
249
250 function resetModeState(cm) {
251 cm.doc.iter(function(line) {
252 if (line.stateAfter) line.stateAfter = null;
253 if (line.styles) line.styles = null;
254 });
255 cm.doc.frontier = cm.doc.first;
256 startWorker(cm, 100);
257 cm.state.modeGen++;
258 if (cm.curOp) regChange(cm);
259 }
260
261 function wrappingChanged(cm) {
262 if (cm.options.lineWrapping) {
263 addClass(cm.display.wrapper, "CodeMirror-wrap");
264 cm.display.sizer.style.minWidth = "";
265 } else {
266 rmClass(cm.display.wrapper, "CodeMirror-wrap");
267 findMaxLine(cm);
268 }
269 estimateLineHeights(cm);
270 regChange(cm);
271 clearCaches(cm);
272 setTimeout(function(){updateScrollbars(cm);}, 100);
273 }
274
275 // Returns a function that estimates the height of a line, to use as
276 // first approximation until the line becomes visible (and is thus
277 // properly measurable).
278 function estimateHeight(cm) {
279 var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
280 var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
281 return function(line) {
282 if (lineIsHidden(cm.doc, line)) return 0;
283
284 var widgetsHeight = 0;
285 if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
286 if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
287 }
288
289 if (wrapping)
290 return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
291 else
292 return widgetsHeight + th;
293 };
294 }
295
296 function estimateLineHeights(cm) {
297 var doc = cm.doc, est = estimateHeight(cm);
298 doc.iter(function(line) {
299 var estHeight = est(line);
300 if (estHeight != line.height) updateLineHeight(line, estHeight);
301 });
302 }
303
304 function keyMapChanged(cm) {
305 var map = keyMap[cm.options.keyMap], style = map.style;
306 cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
307 (style ? " cm-keymap-" + style : "");
308 }
309
310 function themeChanged(cm) {
311 cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
312 cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
313 clearCaches(cm);
314 }
315
316 function guttersChanged(cm) {
317 updateGutters(cm);
318 regChange(cm);
319 setTimeout(function(){alignHorizontally(cm);}, 20);
320 }
321
322 // Rebuild the gutter elements, ensure the margin to the left of the
323 // code matches their width.
324 function updateGutters(cm) {
325 var gutters = cm.display.gutters, specs = cm.options.gutters;
326 removeChildren(gutters);
327 for (var i = 0; i < specs.length; ++i) {
328 var gutterClass = specs[i];
329 var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
330 if (gutterClass == "CodeMirror-linenumbers") {
331 cm.display.lineGutter = gElt;
332 gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
333 }
334 }
335 gutters.style.display = i ? "" : "none";
336 updateGutterSpace(cm);
337 }
338
339 function updateGutterSpace(cm) {
340 var width = cm.display.gutters.offsetWidth;
341 cm.display.sizer.style.marginLeft = width + "px";
342 cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
343 }
344
345 // Compute the character length of a line, taking into account
346 // collapsed ranges (see markText) that might hide parts, and join
347 // other lines onto it.
348 function lineLength(line) {
349 if (line.height == 0) return 0;
350 var len = line.text.length, merged, cur = line;
351 while (merged = collapsedSpanAtStart(cur)) {
352 var found = merged.find(0, true);
353 cur = found.from.line;
354 len += found.from.ch - found.to.ch;
355 }
356 cur = line;
357 while (merged = collapsedSpanAtEnd(cur)) {
358 var found = merged.find(0, true);
359 len -= cur.text.length - found.from.ch;
360 cur = found.to.line;
361 len += cur.text.length - found.to.ch;
362 }
363 return len;
364 }
365
366 // Find the longest line in the document.
367 function findMaxLine(cm) {
368 var d = cm.display, doc = cm.doc;
369 d.maxLine = getLine(doc, doc.first);
370 d.maxLineLength = lineLength(d.maxLine);
371 d.maxLineChanged = true;
372 doc.iter(function(line) {
373 var len = lineLength(line);
374 if (len > d.maxLineLength) {
375 d.maxLineLength = len;
376 d.maxLine = line;
377 }
378 });
379 }
380
381 // Make sure the gutters options contains the element
382 // "CodeMirror-linenumbers" when the lineNumbers option is true.
383 function setGuttersForLineNumbers(options) {
384 var found = indexOf(options.gutters, "CodeMirror-linenumbers");
385 if (found == -1 && options.lineNumbers) {
386 options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
387 } else if (found > -1 && !options.lineNumbers) {
388 options.gutters = options.gutters.slice(0);
389 options.gutters.splice(found, 1);
390 }
391 }
392
393 // SCROLLBARS
394
395 function hScrollbarTakesSpace(cm) {
396 return cm.display.scroller.clientHeight - cm.display.wrapper.clientHeight < scrollerCutOff - 3;
397 }
398
399 // Prepare DOM reads needed to update the scrollbars. Done in one
400 // shot to minimize update/measure roundtrips.
401 function measureForScrollbars(cm) {
402 var scroll = cm.display.scroller;
403 return {
404 clientHeight: scroll.clientHeight,
405 barHeight: cm.display.scrollbarV.clientHeight,
406 scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth,
407 hScrollbarTakesSpace: hScrollbarTakesSpace(cm),
408 barWidth: cm.display.scrollbarH.clientWidth,
409 docHeight: Math.round(cm.doc.height + paddingVert(cm.display))
410 };
411 }
412
413 // Re-synchronize the fake scrollbars with the actual size of the
414 // content.
415 function updateScrollbars(cm, measure) {
416 if (!measure) measure = measureForScrollbars(cm);
417 var d = cm.display, sWidth = scrollbarWidth(d.measure);
418 var scrollHeight = measure.docHeight + scrollerCutOff;
419 var needsH = measure.scrollWidth > measure.clientWidth;
420 if (needsH && measure.scrollWidth <= measure.clientWidth + 1 &&
421 sWidth > 0 && !measure.hScrollbarTakesSpace)
422 needsH = false; // (Issue #2562)
423 var needsV = scrollHeight > measure.clientHeight;
424
425 if (needsV) {
426 d.scrollbarV.style.display = "block";
427 d.scrollbarV.style.bottom = needsH ? sWidth + "px" : "0";
428 // A bug in IE8 can cause this value to be negative, so guard it.
429 d.scrollbarV.firstChild.style.height =
430 Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
431 } else {
432 d.scrollbarV.style.display = "";
433 d.scrollbarV.firstChild.style.height = "0";
434 }
435 if (needsH) {
436 d.scrollbarH.style.display = "block";
437 d.scrollbarH.style.right = needsV ? sWidth + "px" : "0";
438 d.scrollbarH.firstChild.style.width =
439 (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
440 } else {
441 d.scrollbarH.style.display = "";
442 d.scrollbarH.firstChild.style.width = "0";
443 }
444 if (needsH && needsV) {
445 d.scrollbarFiller.style.display = "block";
446 d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = sWidth + "px";
447 } else d.scrollbarFiller.style.display = "";
448 if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
449 d.gutterFiller.style.display = "block";
450 d.gutterFiller.style.height = sWidth + "px";
451 d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
452 } else d.gutterFiller.style.display = "";
453
454 if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) {
455 if (sWidth === 0) {
456 var w = mac && !mac_geMountainLion ? "12px" : "18px";
457 d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w;
458 var barMouseDown = function(e) {
459 if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
460 operation(cm, onMouseDown)(e);
461 };
462 on(d.scrollbarV, "mousedown", barMouseDown);
463 on(d.scrollbarH, "mousedown", barMouseDown);
464 }
465 cm.state.checkedOverlayScrollbar = true;
466 }
467 }
468
469 // Compute the lines that are visible in a given viewport (defaults
470 // the the current scroll position). viewport may contain top,
471 // height, and ensure (see op.scrollToPos) properties.
472 function visibleLines(display, doc, viewport) {
473 var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
474 top = Math.floor(top - paddingTop(display));
475 var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
476
477 var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
478 // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
479 // forces those lines into the viewport (if possible).
480 if (viewport && viewport.ensure) {
481 var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
482 if (ensureFrom < from)
483 return {from: ensureFrom,
484 to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
485 if (Math.min(ensureTo, doc.lastLine()) >= to)
486 return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
487 to: ensureTo};
488 }
489 return {from: from, to: Math.max(to, from + 1)};
490 }
491
492 // LINE NUMBERS
493
494 // Re-align line numbers and gutter marks to compensate for
495 // horizontal scrolling.
496 function alignHorizontally(cm) {
497 var display = cm.display, view = display.view;
498 if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
499 var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
500 var gutterW = display.gutters.offsetWidth, left = comp + "px";
501 for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
502 if (cm.options.fixedGutter && view[i].gutter)
503 view[i].gutter.style.left = left;
504 var align = view[i].alignable;
505 if (align) for (var j = 0; j < align.length; j++)
506 align[j].style.left = left;
507 }
508 if (cm.options.fixedGutter)
509 display.gutters.style.left = (comp + gutterW) + "px";
510 }
511
512 // Used to ensure that the line number gutter is still the right
513 // size for the current document size. Returns true when an update
514 // is needed.
515 function maybeUpdateLineNumberWidth(cm) {
516 if (!cm.options.lineNumbers) return false;
517 var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
518 if (last.length != display.lineNumChars) {
519 var test = display.measure.appendChild(elt("div", [elt("div", last)],
520 "CodeMirror-linenumber CodeMirror-gutter-elt"));
521 var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
522 display.lineGutter.style.width = "";
523 display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
524 display.lineNumWidth = display.lineNumInnerWidth + padding;
525 display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
526 display.lineGutter.style.width = display.lineNumWidth + "px";
527 updateGutterSpace(cm);
528 return true;
529 }
530 return false;
531 }
532
533 function lineNumberFor(options, i) {
534 return String(options.lineNumberFormatter(i + options.firstLineNumber));
535 }
536
537 // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
538 // but using getBoundingClientRect to get a sub-pixel-accurate
539 // result.
540 function compensateForHScroll(display) {
541 return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
542 }
543
544 // DISPLAY DRAWING
545
546 function DisplayUpdate(cm, viewport, force) {
547 var display = cm.display;
548
549 this.viewport = viewport;
550 // Store some values that we'll need later (but don't want to force a relayout for)
551 this.visible = visibleLines(display, cm.doc, viewport);
552 this.editorIsHidden = !display.wrapper.offsetWidth;
553 this.wrapperHeight = display.wrapper.clientHeight;
554 this.oldViewFrom = display.viewFrom; this.oldViewTo = display.viewTo;
555 this.oldScrollerWidth = display.scroller.clientWidth;
556 this.force = force;
557 this.dims = getDimensions(cm);
558 }
559
560 // Does the actual updating of the line display. Bails out
561 // (returning false) when there is nothing to be done and forced is
562 // false.
563 function updateDisplayIfNeeded(cm, update) {
564 var display = cm.display, doc = cm.doc;
565 if (update.editorIsHidden) {
566 resetView(cm);
567 return false;
568 }
569
570 // Bail out if the visible area is already rendered and nothing changed.
571 if (!update.force &&
572 update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
573 (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
574 countDirtyView(cm) == 0)
575 return false;
576
577 if (maybeUpdateLineNumberWidth(cm)) {
578 resetView(cm);
579 update.dims = getDimensions(cm);
580 }
581
582 // Compute a suitable new viewport (from & to)
583 var end = doc.first + doc.size;
584 var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
585 var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
586 if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
587 if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
588 if (sawCollapsedSpans) {
589 from = visualLineNo(cm.doc, from);
590 to = visualLineEndNo(cm.doc, to);
591 }
592
593 var different = from != display.viewFrom || to != display.viewTo ||
594 display.lastSizeC != update.wrapperHeight;
595 adjustView(cm, from, to);
596
597 display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
598 // Position the mover div to align with the current scroll position
599 cm.display.mover.style.top = display.viewOffset + "px";
600
601 var toUpdate = countDirtyView(cm);
602 if (!different && toUpdate == 0 && !update.force &&
603 (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
604 return false;
605
606 // For big changes, we hide the enclosing element during the
607 // update, since that speeds up the operations on most browsers.
608 var focused = activeElt();
609 if (toUpdate > 4) display.lineDiv.style.display = "none";
610 patchDisplay(cm, display.updateLineNumbers, update.dims);
611 if (toUpdate > 4) display.lineDiv.style.display = "";
612 // There might have been a widget with a focused element that got
613 // hidden or updated, if so re-focus it.
614 if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
615
616 // Prevent selection and cursors from interfering with the scroll
617 // width.
618 removeChildren(display.cursorDiv);
619 removeChildren(display.selectionDiv);
620
621 if (different) {
622 display.lastSizeC = update.wrapperHeight;
623 startWorker(cm, 400);
624 }
625
626 display.updateLineNumbers = null;
627
628 return true;
629 }
630
631 function postUpdateDisplay(cm, update) {
632 var force = update.force, viewport = update.viewport;
633 for (var first = true;; first = false) {
634 if (first && cm.options.lineWrapping && update.oldScrollerWidth != cm.display.scroller.clientWidth) {
635 force = true;
636 } else {
637 force = false;
638 // Clip forced viewport to actual scrollable area.
639 if (viewport && viewport.top != null)
640 viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - scrollerCutOff -
641 cm.display.scroller.clientHeight, viewport.top)};
642 // Updated line heights might result in the drawn area not
643 // actually covering the viewport. Keep looping until it does.
644 update.visible = visibleLines(cm.display, cm.doc, viewport);
645 if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
646 break;
647 }
648 if (!updateDisplayIfNeeded(cm, update)) break;
649 updateHeightsInViewport(cm);
650 var barMeasure = measureForScrollbars(cm);
651 updateSelection(cm);
652 setDocumentHeight(cm, barMeasure);
653 updateScrollbars(cm, barMeasure);
654 }
655
656 signalLater(cm, "update", cm);
657 if (cm.display.viewFrom != update.oldViewFrom || cm.display.viewTo != update.oldViewTo)
658 signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
659 }
660
661 function updateDisplaySimple(cm, viewport) {
662 var update = new DisplayUpdate(cm, viewport);
663 if (updateDisplayIfNeeded(cm, update)) {
664 updateHeightsInViewport(cm);
665 postUpdateDisplay(cm, update);
666 var barMeasure = measureForScrollbars(cm);
667 updateSelection(cm);
668 setDocumentHeight(cm, barMeasure);
669 updateScrollbars(cm, barMeasure);
670 }
671 }
672
673 function setDocumentHeight(cm, measure) {
674 cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
675 cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
676 }
677
678 function checkForWebkitWidthBug(cm, measure) {
679 // Work around Webkit bug where it sometimes reserves space for a
680 // non-existing phantom scrollbar in the scroller (Issue #2420)
681 if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) {
682 cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px";
683 cm.display.gutters.style.height = measure.docHeight + "px";
684 }
685 }
686
687 // Read the actual heights of the rendered lines, and update their
688 // stored heights to match.
689 function updateHeightsInViewport(cm) {
690 var display = cm.display;
691 var prevBottom = display.lineDiv.offsetTop;
692 for (var i = 0; i < display.view.length; i++) {
693 var cur = display.view[i], height;
694 if (cur.hidden) continue;
695 if (ie && ie_version < 8) {
696 var bot = cur.node.offsetTop + cur.node.offsetHeight;
697 height = bot - prevBottom;
698 prevBottom = bot;
699 } else {
700 var box = cur.node.getBoundingClientRect();
701 height = box.bottom - box.top;
702 }
703 var diff = cur.line.height - height;
704 if (height < 2) height = textHeight(display);
705 if (diff > .001 || diff < -.001) {
706 updateLineHeight(cur.line, height);
707 updateWidgetHeight(cur.line);
708 if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
709 updateWidgetHeight(cur.rest[j]);
710 }
711 }
712 }
713
714 // Read and store the height of line widgets associated with the
715 // given line.
716 function updateWidgetHeight(line) {
717 if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
718 line.widgets[i].height = line.widgets[i].node.offsetHeight;
719 }
720
721 // Do a bulk-read of the DOM positions and sizes needed to draw the
722 // view, so that we don't interleave reading and writing to the DOM.
723 function getDimensions(cm) {
724 var d = cm.display, left = {}, width = {};
725 var gutterLeft = d.gutters.clientLeft;
726 for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
727 left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
728 width[cm.options.gutters[i]] = n.clientWidth;
729 }
730 return {fixedPos: compensateForHScroll(d),
731 gutterTotalWidth: d.gutters.offsetWidth,
732 gutterLeft: left,
733 gutterWidth: width,
734 wrapperWidth: d.wrapper.clientWidth};
735 }
736
737 // Sync the actual display DOM structure with display.view, removing
738 // nodes for lines that are no longer in view, and creating the ones
739 // that are not there yet, and updating the ones that are out of
740 // date.
741 function patchDisplay(cm, updateNumbersFrom, dims) {
742 var display = cm.display, lineNumbers = cm.options.lineNumbers;
743 var container = display.lineDiv, cur = container.firstChild;
744
745 function rm(node) {
746 var next = node.nextSibling;
747 // Works around a throw-scroll bug in OS X Webkit
748 if (webkit && mac && cm.display.currentWheelTarget == node)
749 node.style.display = "none";
750 else
751 node.parentNode.removeChild(node);
752 return next;
753 }
754
755 var view = display.view, lineN = display.viewFrom;
756 // Loop over the elements in the view, syncing cur (the DOM nodes
757 // in display.lineDiv) with the view as we go.
758 for (var i = 0; i < view.length; i++) {
759 var lineView = view[i];
760 if (lineView.hidden) {
761 } else if (!lineView.node) { // Not drawn yet
762 var node = buildLineElement(cm, lineView, lineN, dims);
763 container.insertBefore(node, cur);
764 } else { // Already drawn
765 while (cur != lineView.node) cur = rm(cur);
766 var updateNumber = lineNumbers && updateNumbersFrom != null &&
767 updateNumbersFrom <= lineN && lineView.lineNumber;
768 if (lineView.changes) {
769 if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
770 updateLineForChanges(cm, lineView, lineN, dims);
771 }
772 if (updateNumber) {
773 removeChildren(lineView.lineNumber);
774 lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
775 }
776 cur = lineView.node.nextSibling;
777 }
778 lineN += lineView.size;
779 }
780 while (cur) cur = rm(cur);
781 }
782
783 // When an aspect of a line changes, a string is added to
784 // lineView.changes. This updates the relevant part of the line's
785 // DOM structure.
786 function updateLineForChanges(cm, lineView, lineN, dims) {
787 for (var j = 0; j < lineView.changes.length; j++) {
788 var type = lineView.changes[j];
789 if (type == "text") updateLineText(cm, lineView);
790 else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
791 else if (type == "class") updateLineClasses(lineView);
792 else if (type == "widget") updateLineWidgets(lineView, dims);
793 }
794 lineView.changes = null;
795 }
796
797 // Lines with gutter elements, widgets or a background class need to
798 // be wrapped, and have the extra elements added to the wrapper div
799 function ensureLineWrapped(lineView) {
800 if (lineView.node == lineView.text) {
801 lineView.node = elt("div", null, null, "position: relative");
802 if (lineView.text.parentNode)
803 lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
804 lineView.node.appendChild(lineView.text);
805 if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
806 }
807 return lineView.node;
808 }
809
810 function updateLineBackground(lineView) {
811 var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
812 if (cls) cls += " CodeMirror-linebackground";
813 if (lineView.background) {
814 if (cls) lineView.background.className = cls;
815 else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
816 } else if (cls) {
817 var wrap = ensureLineWrapped(lineView);
818 lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
819 }
820 }
821
822 // Wrapper around buildLineContent which will reuse the structure
823 // in display.externalMeasured when possible.
824 function getLineContent(cm, lineView) {
825 var ext = cm.display.externalMeasured;
826 if (ext && ext.line == lineView.line) {
827 cm.display.externalMeasured = null;
828 lineView.measure = ext.measure;
829 return ext.built;
830 }
831 return buildLineContent(cm, lineView);
832 }
833
834 // Redraw the line's text. Interacts with the background and text
835 // classes because the mode may output tokens that influence these
836 // classes.
837 function updateLineText(cm, lineView) {
838 var cls = lineView.text.className;
839 var built = getLineContent(cm, lineView);
840 if (lineView.text == lineView.node) lineView.node = built.pre;
841 lineView.text.parentNode.replaceChild(built.pre, lineView.text);
842 lineView.text = built.pre;
843 if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
844 lineView.bgClass = built.bgClass;
845 lineView.textClass = built.textClass;
846 updateLineClasses(lineView);
847 } else if (cls) {
848 lineView.text.className = cls;
849 }
850 }
851
852 function updateLineClasses(lineView) {
853 updateLineBackground(lineView);
854 if (lineView.line.wrapClass)
855 ensureLineWrapped(lineView).className = lineView.line.wrapClass;
856 else if (lineView.node != lineView.text)
857 lineView.node.className = "";
858 var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
859 lineView.text.className = textClass || "";
860 }
861
862 function updateLineGutter(cm, lineView, lineN, dims) {
863 if (lineView.gutter) {
864 lineView.node.removeChild(lineView.gutter);
865 lineView.gutter = null;
866 }
867 var markers = lineView.line.gutterMarkers;
868 if (cm.options.lineNumbers || markers) {
869 var wrap = ensureLineWrapped(lineView);
870 var gutterWrap = lineView.gutter =
871 wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
872 (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
873 lineView.text);
874 if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
875 lineView.lineNumber = gutterWrap.appendChild(
876 elt("div", lineNumberFor(cm.options, lineN),
877 "CodeMirror-linenumber CodeMirror-gutter-elt",
878 "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
879 + cm.display.lineNumInnerWidth + "px"));
880 if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
881 var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
882 if (found)
883 gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
884 dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
885 }
886 }
887 }
888
889 function updateLineWidgets(lineView, dims) {
890 if (lineView.alignable) lineView.alignable = null;
891 for (var node = lineView.node.firstChild, next; node; node = next) {
892 var next = node.nextSibling;
893 if (node.className == "CodeMirror-linewidget")
894 lineView.node.removeChild(node);
895 }
896 insertLineWidgets(lineView, dims);
897 }
898
899 // Build a line's DOM representation from scratch
900 function buildLineElement(cm, lineView, lineN, dims) {
901 var built = getLineContent(cm, lineView);
902 lineView.text = lineView.node = built.pre;
903 if (built.bgClass) lineView.bgClass = built.bgClass;
904 if (built.textClass) lineView.textClass = built.textClass;
905
906 updateLineClasses(lineView);
907 updateLineGutter(cm, lineView, lineN, dims);
908 insertLineWidgets(lineView, dims);
909 return lineView.node;
910 }
911
912 // A lineView may contain multiple logical lines (when merged by
913 // collapsed spans). The widgets for all of them need to be drawn.
914 function insertLineWidgets(lineView, dims) {
915 insertLineWidgetsFor(lineView.line, lineView, dims, true);
916 if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
917 insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
918 }
919
920 function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
921 if (!line.widgets) return;
922 var wrap = ensureLineWrapped(lineView);
923 for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
924 var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
925 if (!widget.handleMouseEvents) node.ignoreEvents = true;
926 positionLineWidget(widget, node, lineView, dims);
927 if (allowAbove && widget.above)
928 wrap.insertBefore(node, lineView.gutter || lineView.text);
929 else
930 wrap.appendChild(node);
931 signalLater(widget, "redraw");
932 }
933 }
934
935 function positionLineWidget(widget, node, lineView, dims) {
936 if (widget.noHScroll) {
937 (lineView.alignable || (lineView.alignable = [])).push(node);
938 var width = dims.wrapperWidth;
939 node.style.left = dims.fixedPos + "px";
940 if (!widget.coverGutter) {
941 width -= dims.gutterTotalWidth;
942 node.style.paddingLeft = dims.gutterTotalWidth + "px";
943 }
944 node.style.width = width + "px";
945 }
946 if (widget.coverGutter) {
947 node.style.zIndex = 5;
948 node.style.position = "relative";
949 if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
950 }
951 }
952
953 // POSITION OBJECT
954
955 // A Pos instance represents a position within the text.
956 var Pos = CodeMirror.Pos = function(line, ch) {
957 if (!(this instanceof Pos)) return new Pos(line, ch);
958 this.line = line; this.ch = ch;
959 };
960
961 // Compare two positions, return 0 if they are the same, a negative
962 // number when a is less, and a positive number otherwise.
963 var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
964
965 function copyPos(x) {return Pos(x.line, x.ch);}
966 function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
967 function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
968
969 // SELECTION / CURSOR
970
971 // Selection objects are immutable. A new one is created every time
972 // the selection changes. A selection is one or more non-overlapping
973 // (and non-touching) ranges, sorted, and an integer that indicates
974 // which one is the primary selection (the one that's scrolled into
975 // view, that getCursor returns, etc).
976 function Selection(ranges, primIndex) {
977 this.ranges = ranges;
978 this.primIndex = primIndex;
979 }
980
981 Selection.prototype = {
982 primary: function() { return this.ranges[this.primIndex]; },
983 equals: function(other) {
984 if (other == this) return true;
985 if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
986 for (var i = 0; i < this.ranges.length; i++) {
987 var here = this.ranges[i], there = other.ranges[i];
988 if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
989 }
990 return true;
991 },
992 deepCopy: function() {
993 for (var out = [], i = 0; i < this.ranges.length; i++)
994 out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
995 return new Selection(out, this.primIndex);
996 },
997 somethingSelected: function() {
998 for (var i = 0; i < this.ranges.length; i++)
999 if (!this.ranges[i].empty()) return true;
1000 return false;
1001 },
1002 contains: function(pos, end) {
1003 if (!end) end = pos;
1004 for (var i = 0; i < this.ranges.length; i++) {
1005 var range = this.ranges[i];
1006 if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
1007 return i;
1008 }
1009 return -1;
1010 }
1011 };
1012
1013 function Range(anchor, head) {
1014 this.anchor = anchor; this.head = head;
1015 }
1016
1017 Range.prototype = {
1018 from: function() { return minPos(this.anchor, this.head); },
1019 to: function() { return maxPos(this.anchor, this.head); },
1020 empty: function() {
1021 return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
1022 }
1023 };
1024
1025 // Take an unsorted, potentially overlapping set of ranges, and
1026 // build a selection out of it. 'Consumes' ranges array (modifying
1027 // it).
1028 function normalizeSelection(ranges, primIndex) {
1029 var prim = ranges[primIndex];
1030 ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
1031 primIndex = indexOf(ranges, prim);
1032 for (var i = 1; i < ranges.length; i++) {
1033 var cur = ranges[i], prev = ranges[i - 1];
1034 if (cmp(prev.to(), cur.from()) >= 0) {
1035 var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
1036 var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
1037 if (i <= primIndex) --primIndex;
1038 ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
1039 }
1040 }
1041 return new Selection(ranges, primIndex);
1042 }
1043
1044 function simpleSelection(anchor, head) {
1045 return new Selection([new Range(anchor, head || anchor)], 0);
1046 }
1047
1048 // Most of the external API clips given positions to make sure they
1049 // actually exist within the document.
1050 function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
1051 function clipPos(doc, pos) {
1052 if (pos.line < doc.first) return Pos(doc.first, 0);
1053 var last = doc.first + doc.size - 1;
1054 if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
1055 return clipToLen(pos, getLine(doc, pos.line).text.length);
1056 }
1057 function clipToLen(pos, linelen) {
1058 var ch = pos.ch;
1059 if (ch == null || ch > linelen) return Pos(pos.line, linelen);
1060 else if (ch < 0) return Pos(pos.line, 0);
1061 else return pos;
1062 }
1063 function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
1064 function clipPosArray(doc, array) {
1065 for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
1066 return out;
1067 }
1068
1069 // SELECTION UPDATES
1070
1071 // The 'scroll' parameter given to many of these indicated whether
1072 // the new cursor position should be scrolled into view after
1073 // modifying the selection.
1074
1075 // If shift is held or the extend flag is set, extends a range to
1076 // include a given position (and optionally a second position).
1077 // Otherwise, simply returns the range between the given positions.
1078 // Used for cursor motion and such.
1079 function extendRange(doc, range, head, other) {
1080 if (doc.cm && doc.cm.display.shift || doc.extend) {
1081 var anchor = range.anchor;
1082 if (other) {
1083 var posBefore = cmp(head, anchor) < 0;
1084 if (posBefore != (cmp(other, anchor) < 0)) {
1085 anchor = head;
1086 head = other;
1087 } else if (posBefore != (cmp(head, other) < 0)) {
1088 head = other;
1089 }
1090 }
1091 return new Range(anchor, head);
1092 } else {
1093 return new Range(other || head, head);
1094 }
1095 }
1096
1097 // Extend the primary selection range, discard the rest.
1098 function extendSelection(doc, head, other, options) {
1099 setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
1100 }
1101
1102 // Extend all selections (pos is an array of selections with length
1103 // equal the number of selections)
1104 function extendSelections(doc, heads, options) {
1105 for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
1106 out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
1107 var newSel = normalizeSelection(out, doc.sel.primIndex);
1108 setSelection(doc, newSel, options);
1109 }
1110
1111 // Updates a single range in the selection.
1112 function replaceOneSelection(doc, i, range, options) {
1113 var ranges = doc.sel.ranges.slice(0);
1114 ranges[i] = range;
1115 setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
1116 }
1117
1118 // Reset the selection to a single range.
1119 function setSimpleSelection(doc, anchor, head, options) {
1120 setSelection(doc, simpleSelection(anchor, head), options);
1121 }
1122
1123 // Give beforeSelectionChange handlers a change to influence a
1124 // selection update.
1125 function filterSelectionChange(doc, sel) {
1126 var obj = {
1127 ranges: sel.ranges,
1128 update: function(ranges) {
1129 this.ranges = [];
1130 for (var i = 0; i < ranges.length; i++)
1131 this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
1132 clipPos(doc, ranges[i].head));
1133 }
1134 };
1135 signal(doc, "beforeSelectionChange", doc, obj);
1136 if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
1137 if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
1138 else return sel;
1139 }
1140
1141 function setSelectionReplaceHistory(doc, sel, options) {
1142 var done = doc.history.done, last = lst(done);
1143 if (last && last.ranges) {
1144 done[done.length - 1] = sel;
1145 setSelectionNoUndo(doc, sel, options);
1146 } else {
1147 setSelection(doc, sel, options);
1148 }
1149 }
1150
1151 // Set a new selection.
1152 function setSelection(doc, sel, options) {
1153 setSelectionNoUndo(doc, sel, options);
1154 addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
1155 }
1156
1157 function setSelectionNoUndo(doc, sel, options) {
1158 if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
1159 sel = filterSelectionChange(doc, sel);
1160
1161 var bias = options && options.bias ||
1162 (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
1163 setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
1164
1165 if (!(options && options.scroll === false) && doc.cm)
1166 ensureCursorVisible(doc.cm);
1167 }
1168
1169 function setSelectionInner(doc, sel) {
1170 if (sel.equals(doc.sel)) return;
1171
1172 doc.sel = sel;
1173
1174 if (doc.cm) {
1175 doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
1176 signalCursorActivity(doc.cm);
1177 }
1178 signalLater(doc, "cursorActivity", doc);
1179 }
1180
1181 // Verify that the selection does not partially select any atomic
1182 // marked ranges.
1183 function reCheckSelection(doc) {
1184 setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
1185 }
1186
1187 // Return a selection that does not partially select any atomic
1188 // ranges.
1189 function skipAtomicInSelection(doc, sel, bias, mayClear) {
1190 var out;
1191 for (var i = 0; i < sel.ranges.length; i++) {
1192 var range = sel.ranges[i];
1193 var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
1194 var newHead = skipAtomic(doc, range.head, bias, mayClear);
1195 if (out || newAnchor != range.anchor || newHead != range.head) {
1196 if (!out) out = sel.ranges.slice(0, i);
1197 out[i] = new Range(newAnchor, newHead);
1198 }
1199 }
1200 return out ? normalizeSelection(out, sel.primIndex) : sel;
1201 }
1202
1203 // Ensure a given position is not inside an atomic range.
1204 function skipAtomic(doc, pos, bias, mayClear) {
1205 var flipped = false, curPos = pos;
1206 var dir = bias || 1;
1207 doc.cantEdit = false;
1208 search: for (;;) {
1209 var line = getLine(doc, curPos.line);
1210 if (line.markedSpans) {
1211 for (var i = 0; i < line.markedSpans.length; ++i) {
1212 var sp = line.markedSpans[i], m = sp.marker;
1213 if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
1214 (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
1215 if (mayClear) {
1216 signal(m, "beforeCursorEnter");
1217 if (m.explicitlyCleared) {
1218 if (!line.markedSpans) break;
1219 else {--i; continue;}
1220 }
1221 }
1222 if (!m.atomic) continue;
1223 var newPos = m.find(dir < 0 ? -1 : 1);
1224 if (cmp(newPos, curPos) == 0) {
1225 newPos.ch += dir;
1226 if (newPos.ch < 0) {
1227 if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
1228 else newPos = null;
1229 } else if (newPos.ch > line.text.length) {
1230 if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
1231 else newPos = null;
1232 }
1233 if (!newPos) {
1234 if (flipped) {
1235 // Driven in a corner -- no valid cursor position found at all
1236 // -- try again *with* clearing, if we didn't already
1237 if (!mayClear) return skipAtomic(doc, pos, bias, true);
1238 // Otherwise, turn off editing until further notice, and return the start of the doc
1239 doc.cantEdit = true;
1240 return Pos(doc.first, 0);
1241 }
1242 flipped = true; newPos = pos; dir = -dir;
1243 }
1244 }
1245 curPos = newPos;
1246 continue search;
1247 }
1248 }
1249 }
1250 return curPos;
1251 }
1252 }
1253
1254 // SELECTION DRAWING
1255
1256 // Redraw the selection and/or cursor
1257 function drawSelection(cm) {
1258 var display = cm.display, doc = cm.doc, result = {};
1259 var curFragment = result.cursors = document.createDocumentFragment();
1260 var selFragment = result.selection = document.createDocumentFragment();
1261
1262 for (var i = 0; i < doc.sel.ranges.length; i++) {
1263 var range = doc.sel.ranges[i];
1264 var collapsed = range.empty();
1265 if (collapsed || cm.options.showCursorWhenSelecting)
1266 drawSelectionCursor(cm, range, curFragment);
1267 if (!collapsed)
1268 drawSelectionRange(cm, range, selFragment);
1269 }
1270
1271 // Move the hidden textarea near the cursor to prevent scrolling artifacts
1272 if (cm.options.moveInputWithCursor) {
1273 var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
1274 var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
1275 result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
1276 headPos.top + lineOff.top - wrapOff.top));
1277 result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
1278 headPos.left + lineOff.left - wrapOff.left));
1279 }
1280
1281 return result;
1282 }
1283
1284 function showSelection(cm, drawn) {
1285 removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
1286 removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
1287 if (drawn.teTop != null) {
1288 cm.display.inputDiv.style.top = drawn.teTop + "px";
1289 cm.display.inputDiv.style.left = drawn.teLeft + "px";
1290 }
1291 }
1292
1293 function updateSelection(cm) {
1294 showSelection(cm, drawSelection(cm));
1295 }
1296
1297 // Draws a cursor for the given range
1298 function drawSelectionCursor(cm, range, output) {
1299 var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
1300
1301 var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
1302 cursor.style.left = pos.left + "px";
1303 cursor.style.top = pos.top + "px";
1304 cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
1305
1306 if (pos.other) {
1307 // Secondary cursor, shown when on a 'jump' in bi-directional text
1308 var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
1309 otherCursor.style.display = "";
1310 otherCursor.style.left = pos.other.left + "px";
1311 otherCursor.style.top = pos.other.top + "px";
1312 otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
1313 }
1314 }
1315
1316 // Draws the given range as a highlighted selection
1317 function drawSelectionRange(cm, range, output) {
1318 var display = cm.display, doc = cm.doc;
1319 var fragment = document.createDocumentFragment();
1320 var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
1321
1322 function add(left, top, width, bottom) {
1323 if (top < 0) top = 0;
1324 top = Math.round(top);
1325 bottom = Math.round(bottom);
1326 fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
1327 "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
1328 "px; height: " + (bottom - top) + "px"));
1329 }
1330
1331 function drawForLine(line, fromArg, toArg) {
1332 var lineObj = getLine(doc, line);
1333 var lineLen = lineObj.text.length;
1334 var start, end;
1335 function coords(ch, bias) {
1336 return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
1337 }
1338
1339 iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
1340 var leftPos = coords(from, "left"), rightPos, left, right;
1341 if (from == to) {
1342 rightPos = leftPos;
1343 left = right = leftPos.left;
1344 } else {
1345 rightPos = coords(to - 1, "right");
1346 if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
1347 left = leftPos.left;
1348 right = rightPos.right;
1349 }
1350 if (fromArg == null && from == 0) left = leftSide;
1351 if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
1352 add(left, leftPos.top, null, leftPos.bottom);
1353 left = leftSide;
1354 if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
1355 }
1356 if (toArg == null && to == lineLen) right = rightSide;
1357 if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
1358 start = leftPos;
1359 if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
1360 end = rightPos;
1361 if (left < leftSide + 1) left = leftSide;
1362 add(left, rightPos.top, right - left, rightPos.bottom);
1363 });
1364 return {start: start, end: end};
1365 }
1366
1367 var sFrom = range.from(), sTo = range.to();
1368 if (sFrom.line == sTo.line) {
1369 drawForLine(sFrom.line, sFrom.ch, sTo.ch);
1370 } else {
1371 var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
1372 var singleVLine = visualLine(fromLine) == visualLine(toLine);
1373 var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
1374 var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
1375 if (singleVLine) {
1376 if (leftEnd.top < rightStart.top - 2) {
1377 add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
1378 add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
1379 } else {
1380 add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
1381 }
1382 }
1383 if (leftEnd.bottom < rightStart.top)
1384 add(leftSide, leftEnd.bottom, null, rightStart.top);
1385 }
1386
1387 output.appendChild(fragment);
1388 }
1389
1390 // Cursor-blinking
1391 function restartBlink(cm) {
1392 if (!cm.state.focused) return;
1393 var display = cm.display;
1394 clearInterval(display.blinker);
1395 var on = true;
1396 display.cursorDiv.style.visibility = "";
1397 if (cm.options.cursorBlinkRate > 0)
1398 display.blinker = setInterval(function() {
1399 display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
1400 }, cm.options.cursorBlinkRate);
1401 else if (cm.options.cursorBlinkRate < 0)
1402 display.cursorDiv.style.visibility = "hidden";
1403 }
1404
1405 // HIGHLIGHT WORKER
1406
1407 function startWorker(cm, time) {
1408 if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
1409 cm.state.highlight.set(time, bind(highlightWorker, cm));
1410 }
1411
1412 function highlightWorker(cm) {
1413 var doc = cm.doc;
1414 if (doc.frontier < doc.first) doc.frontier = doc.first;
1415 if (doc.frontier >= cm.display.viewTo) return;
1416 var end = +new Date + cm.options.workTime;
1417 var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
1418 var changedLines = [];
1419
1420 doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
1421 if (doc.frontier >= cm.display.viewFrom) { // Visible
1422 var oldStyles = line.styles;
1423 var highlighted = highlightLine(cm, line, state, true);
1424 line.styles = highlighted.styles;
1425 var oldCls = line.styleClasses, newCls = highlighted.classes;
1426 if (newCls) line.styleClasses = newCls;
1427 else if (oldCls) line.styleClasses = null;
1428 var ischange = !oldStyles || oldStyles.length != line.styles.length ||
1429 oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
1430 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
1431 if (ischange) changedLines.push(doc.frontier);
1432 line.stateAfter = copyState(doc.mode, state);
1433 } else {
1434 processLine(cm, line.text, state);
1435 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
1436 }
1437 ++doc.frontier;
1438 if (+new Date > end) {
1439 startWorker(cm, cm.options.workDelay);
1440 return true;
1441 }
1442 });
1443 if (changedLines.length) runInOp(cm, function() {
1444 for (var i = 0; i < changedLines.length; i++)
1445 regLineChange(cm, changedLines[i], "text");
1446 });
1447 }
1448
1449 // Finds the line to start with when starting a parse. Tries to
1450 // find a line with a stateAfter, so that it can start with a
1451 // valid state. If that fails, it returns the line with the
1452 // smallest indentation, which tends to need the least context to
1453 // parse correctly.
1454 function findStartLine(cm, n, precise) {
1455 var minindent, minline, doc = cm.doc;
1456 var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
1457 for (var search = n; search > lim; --search) {
1458 if (search <= doc.first) return doc.first;
1459 var line = getLine(doc, search - 1);
1460 if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
1461 var indented = countColumn(line.text, null, cm.options.tabSize);
1462 if (minline == null || minindent > indented) {
1463 minline = search - 1;
1464 minindent = indented;
1465 }
1466 }
1467 return minline;
1468 }
1469
1470 function getStateBefore(cm, n, precise) {
1471 var doc = cm.doc, display = cm.display;
1472 if (!doc.mode.startState) return true;
1473 var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
1474 if (!state) state = startState(doc.mode);
1475 else state = copyState(doc.mode, state);
1476 doc.iter(pos, n, function(line) {
1477 processLine(cm, line.text, state);
1478 var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
1479 line.stateAfter = save ? copyState(doc.mode, state) : null;
1480 ++pos;
1481 });
1482 if (precise) doc.frontier = pos;
1483 return state;
1484 }
1485
1486 // POSITION MEASUREMENT
1487
1488 function paddingTop(display) {return display.lineSpace.offsetTop;}
1489 function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
1490 function paddingH(display) {
1491 if (display.cachedPaddingH) return display.cachedPaddingH;
1492 var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
1493 var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
1494 var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
1495 if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
1496 return data;
1497 }
1498
1499 // Ensure the lineView.wrapping.heights array is populated. This is
1500 // an array of bottom offsets for the lines that make up a drawn
1501 // line. When lineWrapping is on, there might be more than one
1502 // height.
1503 function ensureLineHeights(cm, lineView, rect) {
1504 var wrapping = cm.options.lineWrapping;
1505 var curWidth = wrapping && cm.display.scroller.clientWidth;
1506 if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
1507 var heights = lineView.measure.heights = [];
1508 if (wrapping) {
1509 lineView.measure.width = curWidth;
1510 var rects = lineView.text.firstChild.getClientRects();
1511 for (var i = 0; i < rects.length - 1; i++) {
1512 var cur = rects[i], next = rects[i + 1];
1513 if (Math.abs(cur.bottom - next.bottom) > 2)
1514 heights.push((cur.bottom + next.top) / 2 - rect.top);
1515 }
1516 }
1517 heights.push(rect.bottom - rect.top);
1518 }
1519 }
1520
1521 // Find a line map (mapping character offsets to text nodes) and a
1522 // measurement cache for the given line number. (A line view might
1523 // contain multiple lines when collapsed ranges are present.)
1524 function mapFromLineView(lineView, line, lineN) {
1525 if (lineView.line == line)
1526 return {map: lineView.measure.map, cache: lineView.measure.cache};
1527 for (var i = 0; i < lineView.rest.length; i++)
1528 if (lineView.rest[i] == line)
1529 return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
1530 for (var i = 0; i < lineView.rest.length; i++)
1531 if (lineNo(lineView.rest[i]) > lineN)
1532 return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
1533 }
1534
1535 // Render a line into the hidden node display.externalMeasured. Used
1536 // when measurement is needed for a line that's not in the viewport.
1537 function updateExternalMeasurement(cm, line) {
1538 line = visualLine(line);
1539 var lineN = lineNo(line);
1540 var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
1541 view.lineN = lineN;
1542 var built = view.built = buildLineContent(cm, view);
1543 view.text = built.pre;
1544 removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
1545 return view;
1546 }
1547
1548 // Get a {top, bottom, left, right} box (in line-local coordinates)
1549 // for a given character.
1550 function measureChar(cm, line, ch, bias) {
1551 return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
1552 }
1553
1554 // Find a line view that corresponds to the given line number.
1555 function findViewForLine(cm, lineN) {
1556 if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
1557 return cm.display.view[findViewIndex(cm, lineN)];
1558 var ext = cm.display.externalMeasured;
1559 if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
1560 return ext;
1561 }
1562
1563 // Measurement can be split in two steps, the set-up work that
1564 // applies to the whole line, and the measurement of the actual
1565 // character. Functions like coordsChar, that need to do a lot of
1566 // measurements in a row, can thus ensure that the set-up work is
1567 // only done once.
1568 function prepareMeasureForLine(cm, line) {
1569 var lineN = lineNo(line);
1570 var view = findViewForLine(cm, lineN);
1571 if (view && !view.text)
1572 view = null;
1573 else if (view && view.changes)
1574 updateLineForChanges(cm, view, lineN, getDimensions(cm));
1575 if (!view)
1576 view = updateExternalMeasurement(cm, line);
1577
1578 var info = mapFromLineView(view, line, lineN);
1579 return {
1580 line: line, view: view, rect: null,
1581 map: info.map, cache: info.cache, before: info.before,
1582 hasHeights: false
1583 };
1584 }
1585
1586 // Given a prepared measurement object, measures the position of an
1587 // actual character (or fetches it from the cache).
1588 function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
1589 if (prepared.before) ch = -1;
1590 var key = ch + (bias || ""), found;
1591 if (prepared.cache.hasOwnProperty(key)) {
1592 found = prepared.cache[key];
1593 } else {
1594 if (!prepared.rect)
1595 prepared.rect = prepared.view.text.getBoundingClientRect();
1596 if (!prepared.hasHeights) {
1597 ensureLineHeights(cm, prepared.view, prepared.rect);
1598 prepared.hasHeights = true;
1599 }
1600 found = measureCharInner(cm, prepared, ch, bias);
1601 if (!found.bogus) prepared.cache[key] = found;
1602 }
1603 return {left: found.left, right: found.right,
1604 top: varHeight ? found.rtop : found.top,
1605 bottom: varHeight ? found.rbottom : found.bottom};
1606 }
1607
1608 var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
1609
1610 function measureCharInner(cm, prepared, ch, bias) {
1611 var map = prepared.map;
1612
1613 var node, start, end, collapse;
1614 // First, search the line map for the text node corresponding to,
1615 // or closest to, the target character.
1616 for (var i = 0; i < map.length; i += 3) {
1617 var mStart = map[i], mEnd = map[i + 1];
1618 if (ch < mStart) {
1619 start = 0; end = 1;
1620 collapse = "left";
1621 } else if (ch < mEnd) {
1622 start = ch - mStart;
1623 end = start + 1;
1624 } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
1625 end = mEnd - mStart;
1626 start = end - 1;
1627 if (ch >= mEnd) collapse = "right";
1628 }
1629 if (start != null) {
1630 node = map[i + 2];
1631 if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
1632 collapse = bias;
1633 if (bias == "left" && start == 0)
1634 while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
1635 node = map[(i -= 3) + 2];
1636 collapse = "left";
1637 }
1638 if (bias == "right" && start == mEnd - mStart)
1639 while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
1640 node = map[(i += 3) + 2];
1641 collapse = "right";
1642 }
1643 break;
1644 }
1645 }
1646
1647 var rect;
1648 if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
1649 for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
1650 while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
1651 while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
1652 if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
1653 rect = node.parentNode.getBoundingClientRect();
1654 } else if (ie && cm.options.lineWrapping) {
1655 var rects = range(node, start, end).getClientRects();
1656 if (rects.length)
1657 rect = rects[bias == "right" ? rects.length - 1 : 0];
1658 else
1659 rect = nullRect;
1660 } else {
1661 rect = range(node, start, end).getBoundingClientRect() || nullRect;
1662 }
1663 if (rect.left || rect.right || start == 0) break;
1664 end = start;
1665 start = start - 1;
1666 collapse = "right";
1667 }
1668 if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
1669 } else { // If it is a widget, simply get the box for the whole widget.
1670 if (start > 0) collapse = bias = "right";
1671 var rects;
1672 if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
1673 rect = rects[bias == "right" ? rects.length - 1 : 0];
1674 else
1675 rect = node.getBoundingClientRect();
1676 }
1677 if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
1678 var rSpan = node.parentNode.getClientRects()[0];
1679 if (rSpan)
1680 rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
1681 else
1682 rect = nullRect;
1683 }
1684
1685 var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
1686 var mid = (rtop + rbot) / 2;
1687 var heights = prepared.view.measure.heights;
1688 for (var i = 0; i < heights.length - 1; i++)
1689 if (mid < heights[i]) break;
1690 var top = i ? heights[i - 1] : 0, bot = heights[i];
1691 var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
1692 right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
1693 top: top, bottom: bot};
1694 if (!rect.left && !rect.right) result.bogus = true;
1695 if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
1696
1697 return result;
1698 }
1699
1700 // Work around problem with bounding client rects on ranges being
1701 // returned incorrectly when zoomed on IE10 and below.
1702 function maybeUpdateRectForZooming(measure, rect) {
1703 if (!window.screen || screen.logicalXDPI == null ||
1704 screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
1705 return rect;
1706 var scaleX = screen.logicalXDPI / screen.deviceXDPI;
1707 var scaleY = screen.logicalYDPI / screen.deviceYDPI;
1708 return {left: rect.left * scaleX, right: rect.right * scaleX,
1709 top: rect.top * scaleY, bottom: rect.bottom * scaleY};
1710 }
1711
1712 function clearLineMeasurementCacheFor(lineView) {
1713 if (lineView.measure) {
1714 lineView.measure.cache = {};
1715 lineView.measure.heights = null;
1716 if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
1717 lineView.measure.caches[i] = {};
1718 }
1719 }
1720
1721 function clearLineMeasurementCache(cm) {
1722 cm.display.externalMeasure = null;
1723 removeChildren(cm.display.lineMeasure);
1724 for (var i = 0; i < cm.display.view.length; i++)
1725 clearLineMeasurementCacheFor(cm.display.view[i]);
1726 }
1727
1728 function clearCaches(cm) {
1729 clearLineMeasurementCache(cm);
1730 cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
1731 if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
1732 cm.display.lineNumChars = null;
1733 }
1734
1735 function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
1736 function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
1737
1738 // Converts a {top, bottom, left, right} box from line-local
1739 // coordinates into another coordinate system. Context may be one of
1740 // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
1741 function intoCoordSystem(cm, lineObj, rect, context) {
1742 if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1743 var size = widgetHeight(lineObj.widgets[i]);
1744 rect.top += size; rect.bottom += size;
1745 }
1746 if (context == "line") return rect;
1747 if (!context) context = "local";
1748 var yOff = heightAtLine(lineObj);
1749 if (context == "local") yOff += paddingTop(cm.display);
1750 else yOff -= cm.display.viewOffset;
1751 if (context == "page" || context == "window") {
1752 var lOff = cm.display.lineSpace.getBoundingClientRect();
1753 yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
1754 var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
1755 rect.left += xOff; rect.right += xOff;
1756 }
1757 rect.top += yOff; rect.bottom += yOff;
1758 return rect;
1759 }
1760
1761 // Coverts a box from "div" coords to another coordinate system.
1762 // Context may be "window", "page", "div", or "local"/null.
1763 function fromCoordSystem(cm, coords, context) {
1764 if (context == "div") return coords;
1765 var left = coords.left, top = coords.top;
1766 // First move into "page" coordinate system
1767 if (context == "page") {
1768 left -= pageScrollX();
1769 top -= pageScrollY();
1770 } else if (context == "local" || !context) {
1771 var localBox = cm.display.sizer.getBoundingClientRect();
1772 left += localBox.left;
1773 top += localBox.top;
1774 }
1775
1776 var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
1777 return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
1778 }
1779
1780 function charCoords(cm, pos, context, lineObj, bias) {
1781 if (!lineObj) lineObj = getLine(cm.doc, pos.line);
1782 return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
1783 }
1784
1785 // Returns a box for a given cursor position, which may have an
1786 // 'other' property containing the position of the secondary cursor
1787 // on a bidi boundary.
1788 function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
1789 lineObj = lineObj || getLine(cm.doc, pos.line);
1790 if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
1791 function get(ch, right) {
1792 var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
1793 if (right) m.left = m.right; else m.right = m.left;
1794 return intoCoordSystem(cm, lineObj, m, context);
1795 }
1796 function getBidi(ch, partPos) {
1797 var part = order[partPos], right = part.level % 2;
1798 if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
1799 part = order[--partPos];
1800 ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
1801 right = true;
1802 } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
1803 part = order[++partPos];
1804 ch = bidiLeft(part) - part.level % 2;
1805 right = false;
1806 }
1807 if (right && ch == part.to && ch > part.from) return get(ch - 1);
1808 return get(ch, right);
1809 }
1810 var order = getOrder(lineObj), ch = pos.ch;
1811 if (!order) return get(ch);
1812 var partPos = getBidiPartAt(order, ch);
1813 var val = getBidi(ch, partPos);
1814 if (bidiOther != null) val.other = getBidi(ch, bidiOther);
1815 return val;
1816 }
1817
1818 // Used to cheaply estimate the coordinates for a position. Used for
1819 // intermediate scroll updates.
1820 function estimateCoords(cm, pos) {
1821 var left = 0, pos = clipPos(cm.doc, pos);
1822 if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
1823 var lineObj = getLine(cm.doc, pos.line);
1824 var top = heightAtLine(lineObj) + paddingTop(cm.display);
1825 return {left: left, right: left, top: top, bottom: top + lineObj.height};
1826 }
1827
1828 // Positions returned by coordsChar contain some extra information.
1829 // xRel is the relative x position of the input coordinates compared
1830 // to the found position (so xRel > 0 means the coordinates are to
1831 // the right of the character position, for example). When outside
1832 // is true, that means the coordinates lie outside the line's
1833 // vertical range.
1834 function PosWithInfo(line, ch, outside, xRel) {
1835 var pos = Pos(line, ch);
1836 pos.xRel = xRel;
1837 if (outside) pos.outside = true;
1838 return pos;
1839 }
1840
1841 // Compute the character position closest to the given coordinates.
1842 // Input must be lineSpace-local ("div" coordinate system).
1843 function coordsChar(cm, x, y) {
1844 var doc = cm.doc;
1845 y += cm.display.viewOffset;
1846 if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
1847 var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
1848 if (lineN > last)
1849 return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
1850 if (x < 0) x = 0;
1851
1852 var lineObj = getLine(doc, lineN);
1853 for (;;) {
1854 var found = coordsCharInner(cm, lineObj, lineN, x, y);
1855 var merged = collapsedSpanAtEnd(lineObj);
1856 var mergedPos = merged && merged.find(0, true);
1857 if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
1858 lineN = lineNo(lineObj = mergedPos.to.line);
1859 else
1860 return found;
1861 }
1862 }
1863
1864 function coordsCharInner(cm, lineObj, lineNo, x, y) {
1865 var innerOff = y - heightAtLine(lineObj);
1866 var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
1867 var preparedMeasure = prepareMeasureForLine(cm, lineObj);
1868
1869 function getX(ch) {
1870 var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
1871 wrongLine = true;
1872 if (innerOff > sp.bottom) return sp.left - adjust;
1873 else if (innerOff < sp.top) return sp.left + adjust;
1874 else wrongLine = false;
1875 return sp.left;
1876 }
1877
1878 var bidi = getOrder(lineObj), dist = lineObj.text.length;
1879 var from = lineLeft(lineObj), to = lineRight(lineObj);
1880 var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
1881
1882 if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
1883 // Do a binary search between these bounds.
1884 for (;;) {
1885 if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1886 var ch = x < fromX || x - fromX <= toX - x ? from : to;
1887 var xDiff = x - (ch == from ? fromX : toX);
1888 while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
1889 var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
1890 xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
1891 return pos;
1892 }
1893 var step = Math.ceil(dist / 2), middle = from + step;
1894 if (bidi) {
1895 middle = from;
1896 for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1897 }
1898 var middleX = getX(middle);
1899 if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
1900 else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
1901 }
1902 }
1903
1904 var measureText;
1905 // Compute the default text height.
1906 function textHeight(display) {
1907 if (display.cachedTextHeight != null) return display.cachedTextHeight;
1908 if (measureText == null) {
1909 measureText = elt("pre");
1910 // Measure a bunch of lines, for browsers that compute
1911 // fractional heights.
1912 for (var i = 0; i < 49; ++i) {
1913 measureText.appendChild(document.createTextNode("x"));
1914 measureText.appendChild(elt("br"));
1915 }
1916 measureText.appendChild(document.createTextNode("x"));
1917 }
1918 removeChildrenAndAdd(display.measure, measureText);
1919 var height = measureText.offsetHeight / 50;
1920 if (height > 3) display.cachedTextHeight = height;
1921 removeChildren(display.measure);
1922 return height || 1;
1923 }
1924
1925 // Compute the default character width.
1926 function charWidth(display) {
1927 if (display.cachedCharWidth != null) return display.cachedCharWidth;
1928 var anchor = elt("span", "xxxxxxxxxx");
1929 var pre = elt("pre", [anchor]);
1930 removeChildrenAndAdd(display.measure, pre);
1931 var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
1932 if (width > 2) display.cachedCharWidth = width;
1933 return width || 10;
1934 }
1935
1936 // OPERATIONS
1937
1938 // Operations are used to wrap a series of changes to the editor
1939 // state in such a way that each change won't have to update the
1940 // cursor and display (which would be awkward, slow, and
1941 // error-prone). Instead, display updates are batched and then all
1942 // combined and executed at once.
1943
1944 var operationGroup = null;
1945
1946 var nextOpId = 0;
1947 // Start a new operation.
1948 function startOperation(cm) {
1949 cm.curOp = {
1950 cm: cm,
1951 viewChanged: false, // Flag that indicates that lines might need to be redrawn
1952 startHeight: cm.doc.height, // Used to detect need to update scrollbar
1953 forceUpdate: false, // Used to force a redraw
1954 updateInput: null, // Whether to reset the input textarea
1955 typing: false, // Whether this reset should be careful to leave existing text (for compositing)
1956 changeObjs: null, // Accumulated changes, for firing change events
1957 cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
1958 cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
1959 selectionChanged: false, // Whether the selection needs to be redrawn
1960 updateMaxLine: false, // Set when the widest line needs to be determined anew
1961 scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
1962 scrollToPos: null, // Used to scroll to a specific position
1963 id: ++nextOpId // Unique ID
1964 };
1965 if (operationGroup) {
1966 operationGroup.ops.push(cm.curOp);
1967 } else {
1968 cm.curOp.ownsGroup = operationGroup = {
1969 ops: [cm.curOp],
1970 delayedCallbacks: []
1971 };
1972 }
1973 }
1974
1975 function fireCallbacksForOps(group) {
1976 // Calls delayed callbacks and cursorActivity handlers until no
1977 // new ones appear
1978 var callbacks = group.delayedCallbacks, i = 0;
1979 do {
1980 for (; i < callbacks.length; i++)
1981 callbacks[i]();
1982 for (var j = 0; j < group.ops.length; j++) {
1983 var op = group.ops[j];
1984 if (op.cursorActivityHandlers)
1985 while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
1986 op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
1987 }
1988 } while (i < callbacks.length);
1989 }
1990
1991 // Finish an operation, updating the display and signalling delayed events
1992 function endOperation(cm) {
1993 var op = cm.curOp, group = op.ownsGroup;
1994 if (!group) return;
1995
1996 try { fireCallbacksForOps(group); }
1997 finally {
1998 operationGroup = null;
1999 for (var i = 0; i < group.ops.length; i++)
2000 group.ops[i].cm.curOp = null;
2001 endOperations(group);
2002 }
2003 }
2004
2005 // The DOM updates done when an operation finishes are batched so
2006 // that the minimum number of relayouts are required.
2007 function endOperations(group) {
2008 var ops = group.ops;
2009 for (var i = 0; i < ops.length; i++) // Read DOM
2010 endOperation_R1(ops[i]);
2011 for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
2012 endOperation_W1(ops[i]);
2013 for (var i = 0; i < ops.length; i++) // Read DOM
2014 endOperation_R2(ops[i]);
2015 for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
2016 endOperation_W2(ops[i]);
2017 for (var i = 0; i < ops.length; i++) // Read DOM
2018 endOperation_finish(ops[i]);
2019 }
2020
2021 function endOperation_R1(op) {
2022 var cm = op.cm, display = cm.display;
2023 if (op.updateMaxLine) findMaxLine(cm);
2024
2025 op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
2026 op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
2027 op.scrollToPos.to.line >= display.viewTo) ||
2028 display.maxLineChanged && cm.options.lineWrapping;
2029 op.update = op.mustUpdate &&
2030 new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
2031 }
2032
2033 function endOperation_W1(op) {
2034 op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
2035 }
2036
2037 function endOperation_R2(op) {
2038 var cm = op.cm, display = cm.display;
2039 if (op.updatedDisplay) updateHeightsInViewport(cm);
2040
2041 op.barMeasure = measureForScrollbars(cm);
2042
2043 // If the max line changed since it was last measured, measure it,
2044 // and ensure the document's width matches it.
2045 // updateDisplay_W2 will use these properties to do the actual resizing
2046 if (display.maxLineChanged && !cm.options.lineWrapping) {
2047 op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
2048 op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo +
2049 scrollerCutOff - display.scroller.clientWidth);
2050 }
2051
2052 if (op.updatedDisplay || op.selectionChanged)
2053 op.newSelectionNodes = drawSelection(cm);
2054 }
2055
2056 function endOperation_W2(op) {
2057 var cm = op.cm;
2058
2059 if (op.adjustWidthTo != null) {
2060 cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
2061 if (op.maxScrollLeft < cm.doc.scrollLeft)
2062 setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
2063 cm.display.maxLineChanged = false;
2064 }
2065
2066 if (op.newSelectionNodes)
2067 showSelection(cm, op.newSelectionNodes);
2068 if (op.updatedDisplay)
2069 setDocumentHeight(cm, op.barMeasure);
2070 if (op.updatedDisplay || op.startHeight != cm.doc.height)
2071 updateScrollbars(cm, op.barMeasure);
2072
2073 if (op.selectionChanged) restartBlink(cm);
2074
2075 if (cm.state.focused && op.updateInput)
2076 resetInput(cm, op.typing);
2077 }
2078
2079 function endOperation_finish(op) {
2080 var cm = op.cm, display = cm.display, doc = cm.doc;
2081
2082 if (op.adjustWidthTo != null && Math.abs(op.barMeasure.scrollWidth - cm.display.scroller.scrollWidth) > 1)
2083 updateScrollbars(cm);
2084
2085 if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
2086
2087 // Abort mouse wheel delta measurement, when scrolling explicitly
2088 if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
2089 display.wheelStartX = display.wheelStartY = null;
2090
2091 // Propagate the scroll position to the actual DOM scroller
2092 if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
2093 var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
2094 display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
2095 }
2096 if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
2097 var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
2098 display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
2099 alignHorizontally(cm);
2100 }
2101 // If we need to scroll a specific position into view, do so.
2102 if (op.scrollToPos) {
2103 var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
2104 clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
2105 if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
2106 }
2107
2108 // Fire events for markers that are hidden/unidden by editing or
2109 // undoing
2110 var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
2111 if (hidden) for (var i = 0; i < hidden.length; ++i)
2112 if (!hidden[i].lines.length) signal(hidden[i], "hide");
2113 if (unhidden) for (var i = 0; i < unhidden.length; ++i)
2114 if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
2115
2116 if (display.wrapper.offsetHeight)
2117 doc.scrollTop = cm.display.scroller.scrollTop;
2118
2119 // Apply workaround for two webkit bugs
2120 if (op.updatedDisplay && webkit) {
2121 if (cm.options.lineWrapping)
2122 checkForWebkitWidthBug(cm, op.barMeasure); // (Issue #2420)
2123 if (op.barMeasure.scrollWidth > op.barMeasure.clientWidth &&
2124 op.barMeasure.scrollWidth < op.barMeasure.clientWidth + 1 &&
2125 !hScrollbarTakesSpace(cm))
2126 updateScrollbars(cm); // (Issue #2562)
2127 }
2128
2129 // Fire change events, and delayed event handlers
2130 if (op.changeObjs)
2131 signal(cm, "changes", cm, op.changeObjs);
2132 }
2133
2134 // Run the given function in an operation
2135 function runInOp(cm, f) {
2136 if (cm.curOp) return f();
2137 startOperation(cm);
2138 try { return f(); }
2139 finally { endOperation(cm); }
2140 }
2141 // Wraps a function in an operation. Returns the wrapped function.
2142 function operation(cm, f) {
2143 return function() {
2144 if (cm.curOp) return f.apply(cm, arguments);
2145 startOperation(cm);
2146 try { return f.apply(cm, arguments); }
2147 finally { endOperation(cm); }
2148 };
2149 }
2150 // Used to add methods to editor and doc instances, wrapping them in
2151 // operations.
2152 function methodOp(f) {
2153 return function() {
2154 if (this.curOp) return f.apply(this, arguments);
2155 startOperation(this);
2156 try { return f.apply(this, arguments); }
2157 finally { endOperation(this); }
2158 };
2159 }
2160 function docMethodOp(f) {
2161 return function() {
2162 var cm = this.cm;
2163 if (!cm || cm.curOp) return f.apply(this, arguments);
2164 startOperation(cm);
2165 try { return f.apply(this, arguments); }
2166 finally { endOperation(cm); }
2167 };
2168 }
2169
2170 // VIEW TRACKING
2171
2172 // These objects are used to represent the visible (currently drawn)
2173 // part of the document. A LineView may correspond to multiple
2174 // logical lines, if those are connected by collapsed ranges.
2175 function LineView(doc, line, lineN) {
2176 // The starting line
2177 this.line = line;
2178 // Continuing lines, if any
2179 this.rest = visualLineContinued(line);
2180 // Number of logical lines in this visual line
2181 this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
2182 this.node = this.text = null;
2183 this.hidden = lineIsHidden(doc, line);
2184 }
2185
2186 // Create a range of LineView objects for the given lines.
2187 function buildViewArray(cm, from, to) {
2188 var array = [], nextPos;
2189 for (var pos = from; pos < to; pos = nextPos) {
2190 var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
2191 nextPos = pos + view.size;
2192 array.push(view);
2193 }
2194 return array;
2195 }
2196
2197 // Updates the display.view data structure for a given change to the
2198 // document. From and to are in pre-change coordinates. Lendiff is
2199 // the amount of lines added or subtracted by the change. This is
2200 // used for changes that span multiple lines, or change the way
2201 // lines are divided into visual lines. regLineChange (below)
2202 // registers single-line changes.
2203 function regChange(cm, from, to, lendiff) {
2204 if (from == null) from = cm.doc.first;
2205 if (to == null) to = cm.doc.first + cm.doc.size;
2206 if (!lendiff) lendiff = 0;
2207
2208 var display = cm.display;
2209 if (lendiff && to < display.viewTo &&
2210 (display.updateLineNumbers == null || display.updateLineNumbers > from))
2211 display.updateLineNumbers = from;
2212
2213 cm.curOp.viewChanged = true;
2214
2215 if (from >= display.viewTo) { // Change after
2216 if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
2217 resetView(cm);
2218 } else if (to <= display.viewFrom) { // Change before
2219 if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
2220 resetView(cm);
2221 } else {
2222 display.viewFrom += lendiff;
2223 display.viewTo += lendiff;
2224 }
2225 } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
2226 resetView(cm);
2227 } else if (from <= display.viewFrom) { // Top overlap
2228 var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
2229 if (cut) {
2230 display.view = display.view.slice(cut.index);
2231 display.viewFrom = cut.lineN;
2232 display.viewTo += lendiff;
2233 } else {
2234 resetView(cm);
2235 }
2236 } else if (to >= display.viewTo) { // Bottom overlap
2237 var cut = viewCuttingPoint(cm, from, from, -1);
2238 if (cut) {
2239 display.view = display.view.slice(0, cut.index);
2240 display.viewTo = cut.lineN;
2241 } else {
2242 resetView(cm);
2243 }
2244 } else { // Gap in the middle
2245 var cutTop = viewCuttingPoint(cm, from, from, -1);
2246 var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
2247 if (cutTop && cutBot) {
2248 display.view = display.view.slice(0, cutTop.index)
2249 .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
2250 .concat(display.view.slice(cutBot.index));
2251 display.viewTo += lendiff;
2252 } else {
2253 resetView(cm);
2254 }
2255 }
2256
2257 var ext = display.externalMeasured;
2258 if (ext) {
2259 if (to < ext.lineN)
2260 ext.lineN += lendiff;
2261 else if (from < ext.lineN + ext.size)
2262 display.externalMeasured = null;
2263 }
2264 }
2265
2266 // Register a change to a single line. Type must be one of "text",
2267 // "gutter", "class", "widget"
2268 function regLineChange(cm, line, type) {
2269 cm.curOp.viewChanged = true;
2270 var display = cm.display, ext = cm.display.externalMeasured;
2271 if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
2272 display.externalMeasured = null;
2273
2274 if (line < display.viewFrom || line >= display.viewTo) return;
2275 var lineView = display.view[findViewIndex(cm, line)];
2276 if (lineView.node == null) return;
2277 var arr = lineView.changes || (lineView.changes = []);
2278 if (indexOf(arr, type) == -1) arr.push(type);
2279 }
2280
2281 // Clear the view.
2282 function resetView(cm) {
2283 cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
2284 cm.display.view = [];
2285 cm.display.viewOffset = 0;
2286 }
2287
2288 // Find the view element corresponding to a given line. Return null
2289 // when the line isn't visible.
2290 function findViewIndex(cm, n) {
2291 if (n >= cm.display.viewTo) return null;
2292 n -= cm.display.viewFrom;
2293 if (n < 0) return null;
2294 var view = cm.display.view;
2295 for (var i = 0; i < view.length; i++) {
2296 n -= view[i].size;
2297 if (n < 0) return i;
2298 }
2299 }
2300
2301 function viewCuttingPoint(cm, oldN, newN, dir) {
2302 var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
2303 if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
2304 return {index: index, lineN: newN};
2305 for (var i = 0, n = cm.display.viewFrom; i < index; i++)
2306 n += view[i].size;
2307 if (n != oldN) {
2308 if (dir > 0) {
2309 if (index == view.length - 1) return null;
2310 diff = (n + view[index].size) - oldN;
2311 index++;
2312 } else {
2313 diff = n - oldN;
2314 }
2315 oldN += diff; newN += diff;
2316 }
2317 while (visualLineNo(cm.doc, newN) != newN) {
2318 if (index == (dir < 0 ? 0 : view.length - 1)) return null;
2319 newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
2320 index += dir;
2321 }
2322 return {index: index, lineN: newN};
2323 }
2324
2325 // Force the view to cover a given range, adding empty view element
2326 // or clipping off existing ones as needed.
2327 function adjustView(cm, from, to) {
2328 var display = cm.display, view = display.view;
2329 if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
2330 display.view = buildViewArray(cm, from, to);
2331 display.viewFrom = from;
2332 } else {
2333 if (display.viewFrom > from)
2334 display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
2335 else if (display.viewFrom < from)
2336 display.view = display.view.slice(findViewIndex(cm, from));
2337 display.viewFrom = from;
2338 if (display.viewTo < to)
2339 display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
2340 else if (display.viewTo > to)
2341 display.view = display.view.slice(0, findViewIndex(cm, to));
2342 }
2343 display.viewTo = to;
2344 }
2345
2346 // Count the number of lines in the view whose DOM representation is
2347 // out of date (or nonexistent).
2348 function countDirtyView(cm) {
2349 var view = cm.display.view, dirty = 0;
2350 for (var i = 0; i < view.length; i++) {
2351 var lineView = view[i];
2352 if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
2353 }
2354 return dirty;
2355 }
2356
2357 // INPUT HANDLING
2358
2359 // Poll for input changes, using the normal rate of polling. This
2360 // runs as long as the editor is focused.
2361 function slowPoll(cm) {
2362 if (cm.display.pollingFast) return;
2363 cm.display.poll.set(cm.options.pollInterval, function() {
2364 readInput(cm);
2365 if (cm.state.focused) slowPoll(cm);
2366 });
2367 }
2368
2369 // When an event has just come in that is likely to add or change
2370 // something in the input textarea, we poll faster, to ensure that
2371 // the change appears on the screen quickly.
2372 function fastPoll(cm) {
2373 var missed = false;
2374 cm.display.pollingFast = true;
2375 function p() {
2376 var changed = readInput(cm);
2377 if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
2378 else {cm.display.pollingFast = false; slowPoll(cm);}
2379 }
2380 cm.display.poll.set(20, p);
2381 }
2382
2383 // This will be set to an array of strings when copying, so that,
2384 // when pasting, we know what kind of selections the copied text
2385 // was made out of.
2386 var lastCopied = null;
2387
2388 // Read input from the textarea, and update the document to match.
2389 // When something is selected, it is present in the textarea, and
2390 // selected (unless it is huge, in which case a placeholder is
2391 // used). When nothing is selected, the cursor sits after previously
2392 // seen text (can be empty), which is stored in prevInput (we must
2393 // not reset the textarea when typing, because that breaks IME).
2394 function readInput(cm) {
2395 var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
2396 // Since this is called a *lot*, try to bail out as cheaply as
2397 // possible when it is clear that nothing happened. hasSelection
2398 // will be the case when there is a lot of text in the textarea,
2399 // in which case reading its value would be expensive.
2400 if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput)
2401 return false;
2402 // See paste handler for more on the fakedLastChar kludge
2403 if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
2404 input.value = input.value.substring(0, input.value.length - 1);
2405 cm.state.fakedLastChar = false;
2406 }
2407 var text = input.value;
2408 // If nothing changed, bail.
2409 if (text == prevInput && !cm.somethingSelected()) return false;
2410 // Work around nonsensical selection resetting in IE9/10, and
2411 // inexplicable appearance of private area unicode characters on
2412 // some key combos in Mac (#2689).
2413 if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||
2414 mac && /[\uf700-\uf7ff]/.test(text)) {
2415 resetInput(cm);
2416 return false;
2417 }
2418
2419 var withOp = !cm.curOp;
2420 if (withOp) startOperation(cm);
2421 cm.display.shift = false;
2422
2423 if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
2424 prevInput = "\u200b";
2425 // Find the part of the input that is actually new
2426 var same = 0, l = Math.min(prevInput.length, text.length);
2427 while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
2428 var inserted = text.slice(same), textLines = splitLines(inserted);
2429
2430 // When pasing N lines into N selections, insert one line per selection
2431 var multiPaste = null;
2432 if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {
2433 if (lastCopied && lastCopied.join("\n") == inserted)
2434 multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
2435 else if (textLines.length == doc.sel.ranges.length)
2436 multiPaste = map(textLines, function(l) { return [l]; });
2437 }
2438
2439 // Normal behavior is to insert the new text into every selection
2440 for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
2441 var range = doc.sel.ranges[i];
2442 var from = range.from(), to = range.to();
2443 // Handle deletion
2444 if (same < prevInput.length)
2445 from = Pos(from.line, from.ch - (prevInput.length - same));
2446 // Handle overwrite
2447 else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
2448 to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
2449 var updateInput = cm.curOp.updateInput;
2450 var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
2451 origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
2452 makeChange(cm.doc, changeEvent);
2453 signalLater(cm, "inputRead", cm, changeEvent);
2454 // When an 'electric' character is inserted, immediately trigger a reindent
2455 if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
2456 cm.options.smartIndent && range.head.ch < 100 &&
2457 (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
2458 var mode = cm.getModeAt(range.head);
2459 var end = changeEnd(changeEvent);
2460 if (mode.electricChars) {
2461 for (var j = 0; j < mode.electricChars.length; j++)
2462 if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
2463 indentLine(cm, end.line, "smart");
2464 break;
2465 }
2466 } else if (mode.electricInput) {
2467 if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
2468 indentLine(cm, end.line, "smart");
2469 }
2470 }
2471 }
2472 ensureCursorVisible(cm);
2473 cm.curOp.updateInput = updateInput;
2474 cm.curOp.typing = true;
2475
2476 // Don't leave long text in the textarea, since it makes further polling slow
2477 if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
2478 else cm.display.prevInput = text;
2479 if (withOp) endOperation(cm);
2480 cm.state.pasteIncoming = cm.state.cutIncoming = false;
2481 return true;
2482 }
2483
2484 // Reset the input to correspond to the selection (or to be empty,
2485 // when not typing and nothing is selected)
2486 function resetInput(cm, typing) {
2487 var minimal, selected, doc = cm.doc;
2488 if (cm.somethingSelected()) {
2489 cm.display.prevInput = "";
2490 var range = doc.sel.primary();
2491 minimal = hasCopyEvent &&
2492 (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
2493 var content = minimal ? "-" : selected || cm.getSelection();
2494 cm.display.input.value = content;
2495 if (cm.state.focused) selectInput(cm.display.input);
2496 if (ie && ie_version >= 9) cm.display.inputHasSelection = content;
2497 } else if (!typing) {
2498 cm.display.prevInput = cm.display.input.value = "";
2499 if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
2500 }
2501 cm.display.inaccurateSelection = minimal;
2502 }
2503
2504 function focusInput(cm) {
2505 if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
2506 cm.display.input.focus();
2507 }
2508
2509 function ensureFocus(cm) {
2510 if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
2511 }
2512
2513 function isReadOnly(cm) {
2514 return cm.options.readOnly || cm.doc.cantEdit;
2515 }
2516
2517 // EVENT HANDLERS
2518
2519 // Attach the necessary event handlers when initializing the editor
2520 function registerEventHandlers(cm) {
2521 var d = cm.display;
2522 on(d.scroller, "mousedown", operation(cm, onMouseDown));
2523 // Older IE's will not fire a second mousedown for a double click
2524 if (ie && ie_version < 11)
2525 on(d.scroller, "dblclick", operation(cm, function(e) {
2526 if (signalDOMEvent(cm, e)) return;
2527 var pos = posFromMouse(cm, e);
2528 if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
2529 e_preventDefault(e);
2530 var word = cm.findWordAt(pos);
2531 extendSelection(cm.doc, word.anchor, word.head);
2532 }));
2533 else
2534 on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
2535 // Prevent normal selection in the editor (we handle our own)
2536 on(d.lineSpace, "selectstart", function(e) {
2537 if (!eventInWidget(d, e)) e_preventDefault(e);
2538 });
2539 // Some browsers fire contextmenu *after* opening the menu, at
2540 // which point we can't mess with it anymore. Context menu is
2541 // handled in onMouseDown for these browsers.
2542 if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
2543
2544 // Sync scrolling between fake scrollbars and real scrollable
2545 // area, ensure viewport is updated when scrolling.
2546 on(d.scroller, "scroll", function() {
2547 if (d.scroller.clientHeight) {
2548 setScrollTop(cm, d.scroller.scrollTop);
2549 setScrollLeft(cm, d.scroller.scrollLeft, true);
2550 signal(cm, "scroll", cm);
2551 }
2552 });
2553 on(d.scrollbarV, "scroll", function() {
2554 if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
2555 });
2556 on(d.scrollbarH, "scroll", function() {
2557 if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
2558 });
2559
2560 // Listen to wheel events in order to try and update the viewport on time.
2561 on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
2562 on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
2563
2564 // Prevent clicks in the scrollbars from killing focus
2565 function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
2566 on(d.scrollbarH, "mousedown", reFocus);
2567 on(d.scrollbarV, "mousedown", reFocus);
2568 // Prevent wrapper from ever scrolling
2569 on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
2570
2571 on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
2572 on(d.input, "input", function() {
2573 if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
2574 fastPoll(cm);
2575 });
2576 on(d.input, "keydown", operation(cm, onKeyDown));
2577 on(d.input, "keypress", operation(cm, onKeyPress));
2578 on(d.input, "focus", bind(onFocus, cm));
2579 on(d.input, "blur", bind(onBlur, cm));
2580
2581 function drag_(e) {
2582 if (!signalDOMEvent(cm, e)) e_stop(e);
2583 }
2584 if (cm.options.dragDrop) {
2585 on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
2586 on(d.scroller, "dragenter", drag_);
2587 on(d.scroller, "dragover", drag_);
2588 on(d.scroller, "drop", operation(cm, onDrop));
2589 }
2590 on(d.scroller, "paste", function(e) {
2591 if (eventInWidget(d, e)) return;
2592 cm.state.pasteIncoming = true;
2593 focusInput(cm);
2594 fastPoll(cm);
2595 });
2596 on(d.input, "paste", function() {
2597 // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
2598 // Add a char to the end of textarea before paste occur so that
2599 // selection doesn't span to the end of textarea.
2600 if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
2601 var start = d.input.selectionStart, end = d.input.selectionEnd;
2602 d.input.value += "$";
2603 // The selection end needs to be set before the start, otherwise there
2604 // can be an intermediate non-empty selection between the two, which
2605 // can override the middle-click paste buffer on linux and cause the
2606 // wrong thing to get pasted.
2607 d.input.selectionEnd = end;
2608 d.input.selectionStart = start;
2609 cm.state.fakedLastChar = true;
2610 }
2611 cm.state.pasteIncoming = true;
2612 fastPoll(cm);
2613 });
2614
2615 function prepareCopyCut(e) {
2616 if (cm.somethingSelected()) {
2617 lastCopied = cm.getSelections();
2618 if (d.inaccurateSelection) {
2619 d.prevInput = "";
2620 d.inaccurateSelection = false;
2621 d.input.value = lastCopied.join("\n");
2622 selectInput(d.input);
2623 }
2624 } else {
2625 var text = [], ranges = [];
2626 for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
2627 var line = cm.doc.sel.ranges[i].head.line;
2628 var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
2629 ranges.push(lineRange);
2630 text.push(cm.getRange(lineRange.anchor, lineRange.head));
2631 }
2632 if (e.type == "cut") {
2633 cm.setSelections(ranges, null, sel_dontScroll);
2634 } else {
2635 d.prevInput = "";
2636 d.input.value = text.join("\n");
2637 selectInput(d.input);
2638 }
2639 lastCopied = text;
2640 }
2641 if (e.type == "cut") cm.state.cutIncoming = true;
2642 }
2643 on(d.input, "cut", prepareCopyCut);
2644 on(d.input, "copy", prepareCopyCut);
2645
2646 // Needed to handle Tab key in KHTML
2647 if (khtml) on(d.sizer, "mouseup", function() {
2648 if (activeElt() == d.input) d.input.blur();
2649 focusInput(cm);
2650 });
2651 }
2652
2653 // Called when the window resizes
2654 function onResize(cm) {
2655 // Might be a text scaling operation, clear size caches.
2656 var d = cm.display;
2657 d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
2658 cm.setSize();
2659 }
2660
2661 // MOUSE EVENTS
2662
2663 // Return true when the given mouse event happened in a widget
2664 function eventInWidget(display, e) {
2665 for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
2666 if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
2667 }
2668 }
2669
2670 // Given a mouse event, find the corresponding position. If liberal
2671 // is false, it checks whether a gutter or scrollbar was clicked,
2672 // and returns null if it was. forRect is used by rectangular
2673 // selections, and tries to estimate a character position even for
2674 // coordinates beyond the right of the text.
2675 function posFromMouse(cm, e, liberal, forRect) {
2676 var display = cm.display;
2677 if (!liberal) {
2678 var target = e_target(e);
2679 if (target == display.scrollbarH || target == display.scrollbarV ||
2680 target == display.scrollbarFiller || target == display.gutterFiller) return null;
2681 }
2682 var x, y, space = display.lineSpace.getBoundingClientRect();
2683 // Fails unpredictably on IE[67] when mouse is dragged around quickly.
2684 try { x = e.clientX - space.left; y = e.clientY - space.top; }
2685 catch (e) { return null; }
2686 var coords = coordsChar(cm, x, y), line;
2687 if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
2688 var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
2689 coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
2690 }
2691 return coords;
2692 }
2693
2694 // A mouse down can be a single click, double click, triple click,
2695 // start of selection drag, start of text drag, new cursor
2696 // (ctrl-click), rectangle drag (alt-drag), or xwin
2697 // middle-click-paste. Or it might be a click on something we should
2698 // not interfere with, such as a scrollbar or widget.
2699 function onMouseDown(e) {
2700 if (signalDOMEvent(this, e)) return;
2701 var cm = this, display = cm.display;
2702 display.shift = e.shiftKey;
2703
2704 if (eventInWidget(display, e)) {
2705 if (!webkit) {
2706 // Briefly turn off draggability, to allow widgets to do
2707 // normal dragging things.
2708 display.scroller.draggable = false;
2709 setTimeout(function(){display.scroller.draggable = true;}, 100);
2710 }
2711 return;
2712 }
2713 if (clickInGutter(cm, e)) return;
2714 var start = posFromMouse(cm, e);
2715 window.focus();
2716
2717 switch (e_button(e)) {
2718 case 1:
2719 if (start)
2720 leftButtonDown(cm, e, start);
2721 else if (e_target(e) == display.scroller)
2722 e_preventDefault(e);
2723 break;
2724 case 2:
2725 if (webkit) cm.state.lastMiddleDown = +new Date;
2726 if (start) extendSelection(cm.doc, start);
2727 setTimeout(bind(focusInput, cm), 20);
2728 e_preventDefault(e);
2729 break;
2730 case 3:
2731 if (captureRightClick) onContextMenu(cm, e);
2732 break;
2733 }
2734 }
2735
2736 var lastClick, lastDoubleClick;
2737 function leftButtonDown(cm, e, start) {
2738 setTimeout(bind(ensureFocus, cm), 0);
2739
2740 var now = +new Date, type;
2741 if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
2742 type = "triple";
2743 } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
2744 type = "double";
2745 lastDoubleClick = {time: now, pos: start};
2746 } else {
2747 type = "single";
2748 lastClick = {time: now, pos: start};
2749 }
2750
2751 var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
2752 if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
2753 type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
2754 leftButtonStartDrag(cm, e, start, modifier);
2755 else
2756 leftButtonSelect(cm, e, start, type, modifier);
2757 }
2758
2759 // Start a text drag. When it ends, see if any dragging actually
2760 // happen, and treat as a click if it didn't.
2761 function leftButtonStartDrag(cm, e, start, modifier) {
2762 var display = cm.display;
2763 var dragEnd = operation(cm, function(e2) {
2764 if (webkit) display.scroller.draggable = false;
2765 cm.state.draggingText = false;
2766 off(document, "mouseup", dragEnd);
2767 off(display.scroller, "drop", dragEnd);
2768 if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
2769 e_preventDefault(e2);
2770 if (!modifier)
2771 extendSelection(cm.doc, start);
2772 focusInput(cm);
2773 // Work around unexplainable focus problem in IE9 (#2127)
2774 if (ie && ie_version == 9)
2775 setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
2776 }
2777 });
2778 // Let the drag handler handle this.
2779 if (webkit) display.scroller.draggable = true;
2780 cm.state.draggingText = dragEnd;
2781 // IE's approach to draggable
2782 if (display.scroller.dragDrop) display.scroller.dragDrop();
2783 on(document, "mouseup", dragEnd);
2784 on(display.scroller, "drop", dragEnd);
2785 }
2786
2787 // Normal selection, as opposed to text dragging.
2788 function leftButtonSelect(cm, e, start, type, addNew) {
2789 var display = cm.display, doc = cm.doc;
2790 e_preventDefault(e);
2791
2792 var ourRange, ourIndex, startSel = doc.sel;
2793 if (addNew && !e.shiftKey) {
2794 ourIndex = doc.sel.contains(start);
2795 if (ourIndex > -1)
2796 ourRange = doc.sel.ranges[ourIndex];
2797 else
2798 ourRange = new Range(start, start);
2799 } else {
2800 ourRange = doc.sel.primary();
2801 }
2802
2803 if (e.altKey) {
2804 type = "rect";
2805 if (!addNew) ourRange = new Range(start, start);
2806 start = posFromMouse(cm, e, true, true);
2807 ourIndex = -1;
2808 } else if (type == "double") {
2809 var word = cm.findWordAt(start);
2810 if (cm.display.shift || doc.extend)
2811 ourRange = extendRange(doc, ourRange, word.anchor, word.head);
2812 else
2813 ourRange = word;
2814 } else if (type == "triple") {
2815 var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
2816 if (cm.display.shift || doc.extend)
2817 ourRange = extendRange(doc, ourRange, line.anchor, line.head);
2818 else
2819 ourRange = line;
2820 } else {
2821 ourRange = extendRange(doc, ourRange, start);
2822 }
2823
2824 if (!addNew) {
2825 ourIndex = 0;
2826 setSelection(doc, new Selection([ourRange], 0), sel_mouse);
2827 startSel = doc.sel;
2828 } else if (ourIndex > -1) {
2829 replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
2830 } else {
2831 ourIndex = doc.sel.ranges.length;
2832 setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
2833 {scroll: false, origin: "*mouse"});
2834 }
2835
2836 var lastPos = start;
2837 function extendTo(pos) {
2838 if (cmp(lastPos, pos) == 0) return;
2839 lastPos = pos;
2840
2841 if (type == "rect") {
2842 var ranges = [], tabSize = cm.options.tabSize;
2843 var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
2844 var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
2845 var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
2846 for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
2847 line <= end; line++) {
2848 var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
2849 if (left == right)
2850 ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
2851 else if (text.length > leftPos)
2852 ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
2853 }
2854 if (!ranges.length) ranges.push(new Range(start, start));
2855 setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
2856 {origin: "*mouse", scroll: false});
2857 cm.scrollIntoView(pos);
2858 } else {
2859 var oldRange = ourRange;
2860 var anchor = oldRange.anchor, head = pos;
2861 if (type != "single") {
2862 if (type == "double")
2863 var range = cm.findWordAt(pos);
2864 else
2865 var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
2866 if (cmp(range.anchor, anchor) > 0) {
2867 head = range.head;
2868 anchor = minPos(oldRange.from(), range.anchor);
2869 } else {
2870 head = range.anchor;
2871 anchor = maxPos(oldRange.to(), range.head);
2872 }
2873 }
2874 var ranges = startSel.ranges.slice(0);
2875 ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
2876 setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
2877 }
2878 }
2879
2880 var editorSize = display.wrapper.getBoundingClientRect();
2881 // Used to ensure timeout re-tries don't fire when another extend
2882 // happened in the meantime (clearTimeout isn't reliable -- at
2883 // least on Chrome, the timeouts still happen even when cleared,
2884 // if the clear happens after their scheduled firing time).
2885 var counter = 0;
2886
2887 function extend(e) {
2888 var curCount = ++counter;
2889 var cur = posFromMouse(cm, e, true, type == "rect");
2890 if (!cur) return;
2891 if (cmp(cur, lastPos) != 0) {
2892 ensureFocus(cm);
2893 extendTo(cur);
2894 var visible = visibleLines(display, doc);
2895 if (cur.line >= visible.to || cur.line < visible.from)
2896 setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
2897 } else {
2898 var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
2899 if (outside) setTimeout(operation(cm, function() {
2900 if (counter != curCount) return;
2901 display.scroller.scrollTop += outside;
2902 extend(e);
2903 }), 50);
2904 }
2905 }
2906
2907 function done(e) {
2908 counter = Infinity;
2909 e_preventDefault(e);
2910 focusInput(cm);
2911 off(document, "mousemove", move);
2912 off(document, "mouseup", up);
2913 doc.history.lastSelOrigin = null;
2914 }
2915
2916 var move = operation(cm, function(e) {
2917 if (!e_button(e)) done(e);
2918 else extend(e);
2919 });
2920 var up = operation(cm, done);
2921 on(document, "mousemove", move);
2922 on(document, "mouseup", up);
2923 }
2924
2925 // Determines whether an event happened in the gutter, and fires the
2926 // handlers for the corresponding event.
2927 function gutterEvent(cm, e, type, prevent, signalfn) {
2928 try { var mX = e.clientX, mY = e.clientY; }
2929 catch(e) { return false; }
2930 if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
2931 if (prevent) e_preventDefault(e);
2932
2933 var display = cm.display;
2934 var lineBox = display.lineDiv.getBoundingClientRect();
2935
2936 if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
2937 mY -= lineBox.top - display.viewOffset;
2938
2939 for (var i = 0; i < cm.options.gutters.length; ++i) {
2940 var g = display.gutters.childNodes[i];
2941 if (g && g.getBoundingClientRect().right >= mX) {
2942 var line = lineAtHeight(cm.doc, mY);
2943 var gutter = cm.options.gutters[i];
2944 signalfn(cm, type, cm, line, gutter, e);
2945 return e_defaultPrevented(e);
2946 }
2947 }
2948 }
2949
2950 function clickInGutter(cm, e) {
2951 return gutterEvent(cm, e, "gutterClick", true, signalLater);
2952 }
2953
2954 // Kludge to work around strange IE behavior where it'll sometimes
2955 // re-fire a series of drag-related events right after the drop (#1551)
2956 var lastDrop = 0;
2957
2958 function onDrop(e) {
2959 var cm = this;
2960 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
2961 return;
2962 e_preventDefault(e);
2963 if (ie) lastDrop = +new Date;
2964 var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
2965 if (!pos || isReadOnly(cm)) return;
2966 // Might be a file drop, in which case we simply extract the text
2967 // and insert it.
2968 if (files && files.length && window.FileReader && window.File) {
2969 var n = files.length, text = Array(n), read = 0;
2970 var loadFile = function(file, i) {
2971 var reader = new FileReader;
2972 reader.onload = operation(cm, function() {
2973 text[i] = reader.result;
2974 if (++read == n) {
2975 pos = clipPos(cm.doc, pos);
2976 var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
2977 makeChange(cm.doc, change);
2978 setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
2979 }
2980 });
2981 reader.readAsText(file);
2982 };
2983 for (var i = 0; i < n; ++i) loadFile(files[i], i);
2984 } else { // Normal drop
2985 // Don't do a replace if the drop happened inside of the selected text.
2986 if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
2987 cm.state.draggingText(e);
2988 // Ensure the editor is re-focused
2989 setTimeout(bind(focusInput, cm), 20);
2990 return;
2991 }
2992 try {
2993 var text = e.dataTransfer.getData("Text");
2994 if (text) {
2995 if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
2996 var selected = cm.listSelections();
2997 setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
2998 if (selected) for (var i = 0; i < selected.length; ++i)
2999 replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
3000 cm.replaceSelection(text, "around", "paste");
3001 focusInput(cm);
3002 }
3003 }
3004 catch(e){}
3005 }
3006 }
3007
3008 function onDragStart(cm, e) {
3009 if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
3010 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
3011
3012 e.dataTransfer.setData("Text", cm.getSelection());
3013
3014 // Use dummy image instead of default browsers image.
3015 // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
3016 if (e.dataTransfer.setDragImage && !safari) {
3017 var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
3018 img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3019 if (presto) {
3020 img.width = img.height = 1;
3021 cm.display.wrapper.appendChild(img);
3022 // Force a relayout, or Opera won't use our image for some obscure reason
3023 img._top = img.offsetTop;
3024 }
3025 e.dataTransfer.setDragImage(img, 0, 0);
3026 if (presto) img.parentNode.removeChild(img);
3027 }
3028 }
3029
3030 // SCROLL EVENTS
3031
3032 // Sync the scrollable area and scrollbars, ensure the viewport
3033 // covers the visible area.
3034 function setScrollTop(cm, val) {
3035 if (Math.abs(cm.doc.scrollTop - val) < 2) return;
3036 cm.doc.scrollTop = val;
3037 if (!gecko) updateDisplaySimple(cm, {top: val});
3038 if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
3039 if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
3040 if (gecko) updateDisplaySimple(cm);
3041 startWorker(cm, 100);
3042 }
3043 // Sync scroller and scrollbar, ensure the gutter elements are
3044 // aligned.
3045 function setScrollLeft(cm, val, isScroller) {
3046 if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
3047 val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
3048 cm.doc.scrollLeft = val;
3049 alignHorizontally(cm);
3050 if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
3051 if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
3052 }
3053
3054 // Since the delta values reported on mouse wheel events are
3055 // unstandardized between browsers and even browser versions, and
3056 // generally horribly unpredictable, this code starts by measuring
3057 // the scroll effect that the first few mouse wheel events have,
3058 // and, from that, detects the way it can convert deltas to pixel
3059 // offsets afterwards.
3060 //
3061 // The reason we want to know the amount a wheel event will scroll
3062 // is that it gives us a chance to update the display before the
3063 // actual scrolling happens, reducing flickering.
3064
3065 var wheelSamples = 0, wheelPixelsPerUnit = null;
3066 // Fill in a browser-detected starting value on browsers where we
3067 // know one. These don't have to be accurate -- the result of them
3068 // being wrong would just be a slight flicker on the first wheel
3069 // scroll (if it is large enough).
3070 if (ie) wheelPixelsPerUnit = -.53;
3071 else if (gecko) wheelPixelsPerUnit = 15;
3072 else if (chrome) wheelPixelsPerUnit = -.7;
3073 else if (safari) wheelPixelsPerUnit = -1/3;
3074
3075 function onScrollWheel(cm, e) {
3076 var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
3077 if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
3078 if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
3079 else if (dy == null) dy = e.wheelDelta;
3080
3081 var display = cm.display, scroll = display.scroller;
3082 // Quit if there's nothing to scroll here
3083 if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
3084 dy && scroll.scrollHeight > scroll.clientHeight)) return;
3085
3086 // Webkit browsers on OS X abort momentum scrolls when the target
3087 // of the scroll event is removed from the scrollable element.
3088 // This hack (see related code in patchDisplay) makes sure the
3089 // element is kept around.
3090 if (dy && mac && webkit) {
3091 outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
3092 for (var i = 0; i < view.length; i++) {
3093 if (view[i].node == cur) {
3094 cm.display.currentWheelTarget = cur;
3095 break outer;
3096 }
3097 }
3098 }
3099 }
3100
3101 // On some browsers, horizontal scrolling will cause redraws to
3102 // happen before the gutter has been realigned, causing it to
3103 // wriggle around in a most unseemly way. When we have an
3104 // estimated pixels/delta value, we just handle horizontal
3105 // scrolling entirely here. It'll be slightly off from native, but
3106 // better than glitching out.
3107 if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
3108 if (dy)
3109 setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
3110 setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
3111 e_preventDefault(e);
3112 display.wheelStartX = null; // Abort measurement, if in progress
3113 return;
3114 }
3115
3116 // 'Project' the visible viewport to cover the area that is being
3117 // scrolled into view (if we know enough to estimate it).
3118 if (dy && wheelPixelsPerUnit != null) {
3119 var pixels = dy * wheelPixelsPerUnit;
3120 var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
3121 if (pixels < 0) top = Math.max(0, top + pixels - 50);
3122 else bot = Math.min(cm.doc.height, bot + pixels + 50);
3123 updateDisplaySimple(cm, {top: top, bottom: bot});
3124 }
3125
3126 if (wheelSamples < 20) {
3127 if (display.wheelStartX == null) {
3128 display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
3129 display.wheelDX = dx; display.wheelDY = dy;
3130 setTimeout(function() {
3131 if (display.wheelStartX == null) return;
3132 var movedX = scroll.scrollLeft - display.wheelStartX;
3133 var movedY = scroll.scrollTop - display.wheelStartY;
3134 var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
3135 (movedX && display.wheelDX && movedX / display.wheelDX);
3136 display.wheelStartX = display.wheelStartY = null;
3137 if (!sample) return;
3138 wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
3139 ++wheelSamples;
3140 }, 200);
3141 } else {
3142 display.wheelDX += dx; display.wheelDY += dy;
3143 }
3144 }
3145 }
3146
3147 // KEY EVENTS
3148
3149 // Run a handler that was bound to a key.
3150 function doHandleBinding(cm, bound, dropShift) {
3151 if (typeof bound == "string") {
3152 bound = commands[bound];
3153 if (!bound) return false;
3154 }
3155 // Ensure previous input has been read, so that the handler sees a
3156 // consistent view of the document
3157 if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
3158 var prevShift = cm.display.shift, done = false;
3159 try {
3160 if (isReadOnly(cm)) cm.state.suppressEdits = true;
3161 if (dropShift) cm.display.shift = false;
3162 done = bound(cm) != Pass;
3163 } finally {
3164 cm.display.shift = prevShift;
3165 cm.state.suppressEdits = false;
3166 }
3167 return done;
3168 }
3169
3170 // Collect the currently active keymaps.
3171 function allKeyMaps(cm) {
3172 var maps = cm.state.keyMaps.slice(0);
3173 if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
3174 maps.push(cm.options.keyMap);
3175 return maps;
3176 }
3177
3178 var maybeTransition;
3179 // Handle a key from the keydown event.
3180 function handleKeyBinding(cm, e) {
3181 // Handle automatic keymap transitions
3182 var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
3183 clearTimeout(maybeTransition);
3184 if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
3185 if (getKeyMap(cm.options.keyMap) == startMap) {
3186 cm.options.keyMap = (next.call ? next.call(null, cm) : next);
3187 keyMapChanged(cm);
3188 }
3189 }, 50);
3190
3191 var name = keyName(e, true), handled = false;
3192 if (!name) return false;
3193 var keymaps = allKeyMaps(cm);
3194
3195 if (e.shiftKey) {
3196 // First try to resolve full name (including 'Shift-'). Failing
3197 // that, see if there is a cursor-motion command (starting with
3198 // 'go') bound to the keyname without 'Shift-'.
3199 handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
3200 || lookupKey(name, keymaps, function(b) {
3201 if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
3202 return doHandleBinding(cm, b);
3203 });
3204 } else {
3205 handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
3206 }
3207
3208 if (handled) {
3209 e_preventDefault(e);
3210 restartBlink(cm);
3211 signalLater(cm, "keyHandled", cm, name, e);
3212 }
3213 return handled;
3214 }
3215
3216 // Handle a key from the keypress event
3217 function handleCharBinding(cm, e, ch) {
3218 var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
3219 function(b) { return doHandleBinding(cm, b, true); });
3220 if (handled) {
3221 e_preventDefault(e);
3222 restartBlink(cm);
3223 signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
3224 }
3225 return handled;
3226 }
3227
3228 var lastStoppedKey = null;
3229 function onKeyDown(e) {
3230 var cm = this;
3231 ensureFocus(cm);
3232 if (signalDOMEvent(cm, e)) return;
3233 // IE does strange things with escape.
3234 if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
3235 var code = e.keyCode;
3236 cm.display.shift = code == 16 || e.shiftKey;
3237 var handled = handleKeyBinding(cm, e);
3238 if (presto) {
3239 lastStoppedKey = handled ? code : null;
3240 // Opera has no cut event... we try to at least catch the key combo
3241 if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
3242 cm.replaceSelection("", null, "cut");
3243 }
3244
3245 // Turn mouse into crosshair when Alt is held on Mac.
3246 if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
3247 showCrossHair(cm);
3248 }
3249
3250 function showCrossHair(cm) {
3251 var lineDiv = cm.display.lineDiv;
3252 addClass(lineDiv, "CodeMirror-crosshair");
3253
3254 function up(e) {
3255 if (e.keyCode == 18 || !e.altKey) {
3256 rmClass(lineDiv, "CodeMirror-crosshair");
3257 off(document, "keyup", up);
3258 off(document, "mouseover", up);
3259 }
3260 }
3261 on(document, "keyup", up);
3262 on(document, "mouseover", up);
3263 }
3264
3265 function onKeyUp(e) {
3266 if (e.keyCode == 16) this.doc.sel.shift = false;
3267 signalDOMEvent(this, e);
3268 }
3269
3270 function onKeyPress(e) {
3271 var cm = this;
3272 if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
3273 var keyCode = e.keyCode, charCode = e.charCode;
3274 if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
3275 if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
3276 var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
3277 if (handleCharBinding(cm, e, ch)) return;
3278 if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
3279 fastPoll(cm);
3280 }
3281
3282 // FOCUS/BLUR EVENTS
3283
3284 function onFocus(cm) {
3285 if (cm.options.readOnly == "nocursor") return;
3286 if (!cm.state.focused) {
3287 signal(cm, "focus", cm);
3288 cm.state.focused = true;
3289 addClass(cm.display.wrapper, "CodeMirror-focused");
3290 // The prevInput test prevents this from firing when a context
3291 // menu is closed (since the resetInput would kill the
3292 // select-all detection hack)
3293 if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
3294 resetInput(cm);
3295 if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
3296 }
3297 }
3298 slowPoll(cm);
3299 restartBlink(cm);
3300 }
3301 function onBlur(cm) {
3302 if (cm.state.focused) {
3303 signal(cm, "blur", cm);
3304 cm.state.focused = false;
3305 rmClass(cm.display.wrapper, "CodeMirror-focused");
3306 }
3307 clearInterval(cm.display.blinker);
3308 setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
3309 }
3310
3311 // CONTEXT MENU HANDLING
3312
3313 // To make the context menu work, we need to briefly unhide the
3314 // textarea (making it as unobtrusive as possible) to let the
3315 // right-click take effect on it.
3316 function onContextMenu(cm, e) {
3317 if (signalDOMEvent(cm, e, "contextmenu")) return;
3318 var display = cm.display;
3319 if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
3320
3321 var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
3322 if (!pos || presto) return; // Opera is difficult.
3323
3324 // Reset the current text selection only if the click is done outside of the selection
3325 // and 'resetSelectionOnContextMenu' option is true.
3326 var reset = cm.options.resetSelectionOnContextMenu;
3327 if (reset && cm.doc.sel.contains(pos) == -1)
3328 operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
3329
3330 var oldCSS = display.input.style.cssText;
3331 display.inputDiv.style.position = "absolute";
3332 display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
3333 "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
3334 (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
3335 "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
3336 if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
3337 focusInput(cm);
3338 if (webkit) window.scrollTo(null, oldScrollY);
3339 resetInput(cm);
3340 // Adds "Select all" to context menu in FF
3341 if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
3342 display.selForContextMenu = cm.doc.sel;
3343 clearTimeout(display.detectingSelectAll);
3344
3345 // Select-all will be greyed out if there's nothing to select, so
3346 // this adds a zero-width space so that we can later check whether
3347 // it got selected.
3348 function prepareSelectAllHack() {
3349 if (display.input.selectionStart != null) {
3350 var selected = cm.somethingSelected();
3351 var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
3352 display.prevInput = selected ? "" : "\u200b";
3353 display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
3354 // Re-set this, in case some other handler touched the
3355 // selection in the meantime.
3356 display.selForContextMenu = cm.doc.sel;
3357 }
3358 }
3359 function rehide() {
3360 display.inputDiv.style.position = "relative";
3361 display.input.style.cssText = oldCSS;
3362 if (ie && ie_version < 9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
3363 slowPoll(cm);
3364
3365 // Try to detect the user choosing select-all
3366 if (display.input.selectionStart != null) {
3367 if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
3368 var i = 0, poll = function() {
3369 if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
3370 operation(cm, commands.selectAll)(cm);
3371 else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
3372 else resetInput(cm);
3373 };
3374 display.detectingSelectAll = setTimeout(poll, 200);
3375 }
3376 }
3377
3378 if (ie && ie_version >= 9) prepareSelectAllHack();
3379 if (captureRightClick) {
3380 e_stop(e);
3381 var mouseup = function() {
3382 off(window, "mouseup", mouseup);
3383 setTimeout(rehide, 20);
3384 };
3385 on(window, "mouseup", mouseup);
3386 } else {
3387 setTimeout(rehide, 50);
3388 }
3389 }
3390
3391 function contextMenuInGutter(cm, e) {
3392 if (!hasHandler(cm, "gutterContextMenu")) return false;
3393 return gutterEvent(cm, e, "gutterContextMenu", false, signal);
3394 }
3395
3396 // UPDATING
3397
3398 // Compute the position of the end of a change (its 'to' property
3399 // refers to the pre-change end).
3400 var changeEnd = CodeMirror.changeEnd = function(change) {
3401 if (!change.text) return change.to;
3402 return Pos(change.from.line + change.text.length - 1,
3403 lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
3404 };
3405
3406 // Adjust a position to refer to the post-change position of the
3407 // same text, or the end of the change if the change covers it.
3408 function adjustForChange(pos, change) {
3409 if (cmp(pos, change.from) < 0) return pos;
3410 if (cmp(pos, change.to) <= 0) return changeEnd(change);
3411
3412 var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
3413 if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
3414 return Pos(line, ch);
3415 }
3416
3417 function computeSelAfterChange(doc, change) {
3418 var out = [];
3419 for (var i = 0; i < doc.sel.ranges.length; i++) {
3420 var range = doc.sel.ranges[i];
3421 out.push(new Range(adjustForChange(range.anchor, change),
3422 adjustForChange(range.head, change)));
3423 }
3424 return normalizeSelection(out, doc.sel.primIndex);
3425 }
3426
3427 function offsetPos(pos, old, nw) {
3428 if (pos.line == old.line)
3429 return Pos(nw.line, pos.ch - old.ch + nw.ch);
3430 else
3431 return Pos(nw.line + (pos.line - old.line), pos.ch);
3432 }
3433
3434 // Used by replaceSelections to allow moving the selection to the
3435 // start or around the replaced test. Hint may be "start" or "around".
3436 function computeReplacedSel(doc, changes, hint) {
3437 var out = [];
3438 var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
3439 for (var i = 0; i < changes.length; i++) {
3440 var change = changes[i];
3441 var from = offsetPos(change.from, oldPrev, newPrev);
3442 var to = offsetPos(changeEnd(change), oldPrev, newPrev);
3443 oldPrev = change.to;
3444 newPrev = to;
3445 if (hint == "around") {
3446 var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
3447 out[i] = new Range(inv ? to : from, inv ? from : to);
3448 } else {
3449 out[i] = new Range(from, from);
3450 }
3451 }
3452 return new Selection(out, doc.sel.primIndex);
3453 }
3454
3455 // Allow "beforeChange" event handlers to influence a change
3456 function filterChange(doc, change, update) {
3457 var obj = {
3458 canceled: false,
3459 from: change.from,
3460 to: change.to,
3461 text: change.text,
3462 origin: change.origin,
3463 cancel: function() { this.canceled = true; }
3464 };
3465 if (update) obj.update = function(from, to, text, origin) {
3466 if (from) this.from = clipPos(doc, from);
3467 if (to) this.to = clipPos(doc, to);
3468 if (text) this.text = text;
3469 if (origin !== undefined) this.origin = origin;
3470 };
3471 signal(doc, "beforeChange", doc, obj);
3472 if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
3473
3474 if (obj.canceled) return null;
3475 return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
3476 }
3477
3478 // Apply a change to a document, and add it to the document's
3479 // history, and propagating it to all linked documents.
3480 function makeChange(doc, change, ignoreReadOnly) {
3481 if (doc.cm) {
3482 if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
3483 if (doc.cm.state.suppressEdits) return;
3484 }
3485
3486 if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
3487 change = filterChange(doc, change, true);
3488 if (!change) return;
3489 }
3490
3491 // Possibly split or suppress the update based on the presence
3492 // of read-only spans in its range.
3493 var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
3494 if (split) {
3495 for (var i = split.length - 1; i >= 0; --i)
3496 makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
3497 } else {
3498 makeChangeInner(doc, change);
3499 }
3500 }
3501
3502 function makeChangeInner(doc, change) {
3503 if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
3504 var selAfter = computeSelAfterChange(doc, change);
3505 addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
3506
3507 makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
3508 var rebased = [];
3509
3510 linkedDocs(doc, function(doc, sharedHist) {
3511 if (!sharedHist && indexOf(rebased, doc.history) == -1) {
3512 rebaseHist(doc.history, change);
3513 rebased.push(doc.history);
3514 }
3515 makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
3516 });
3517 }
3518
3519 // Revert a change stored in a document's history.
3520 function makeChangeFromHistory(doc, type, allowSelectionOnly) {
3521 if (doc.cm && doc.cm.state.suppressEdits) return;
3522
3523 var hist = doc.history, event, selAfter = doc.sel;
3524 var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
3525
3526 // Verify that there is a useable event (so that ctrl-z won't
3527 // needlessly clear selection events)
3528 for (var i = 0; i < source.length; i++) {
3529 event = source[i];
3530 if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
3531 break;
3532 }
3533 if (i == source.length) return;
3534 hist.lastOrigin = hist.lastSelOrigin = null;
3535
3536 for (;;) {
3537 event = source.pop();
3538 if (event.ranges) {
3539 pushSelectionToHistory(event, dest);
3540 if (allowSelectionOnly && !event.equals(doc.sel)) {
3541 setSelection(doc, event, {clearRedo: false});
3542 return;
3543 }
3544 selAfter = event;
3545 }
3546 else break;
3547 }
3548
3549 // Build up a reverse change object to add to the opposite history
3550 // stack (redo when undoing, and vice versa).
3551 var antiChanges = [];
3552 pushSelectionToHistory(selAfter, dest);
3553 dest.push({changes: antiChanges, generation: hist.generation});
3554 hist.generation = event.generation || ++hist.maxGeneration;
3555
3556 var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
3557
3558 for (var i = event.changes.length - 1; i >= 0; --i) {
3559 var change = event.changes[i];
3560 change.origin = type;
3561 if (filter && !filterChange(doc, change, false)) {
3562 source.length = 0;
3563 return;
3564 }
3565
3566 antiChanges.push(historyChangeFromChange(doc, change));
3567
3568 var after = i ? computeSelAfterChange(doc, change) : lst(source);
3569 makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
3570 if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
3571 var rebased = [];
3572
3573 // Propagate to the linked documents
3574 linkedDocs(doc, function(doc, sharedHist) {
3575 if (!sharedHist && indexOf(rebased, doc.history) == -1) {
3576 rebaseHist(doc.history, change);
3577 rebased.push(doc.history);
3578 }
3579 makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
3580 });
3581 }
3582 }
3583
3584 // Sub-views need their line numbers shifted when text is added
3585 // above or below them in the parent document.
3586 function shiftDoc(doc, distance) {
3587 if (distance == 0) return;
3588 doc.first += distance;
3589 doc.sel = new Selection(map(doc.sel.ranges, function(range) {
3590 return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
3591 Pos(range.head.line + distance, range.head.ch));
3592 }), doc.sel.primIndex);
3593 if (doc.cm) {
3594 regChange(doc.cm, doc.first, doc.first - distance, distance);
3595 for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
3596 regLineChange(doc.cm, l, "gutter");
3597 }
3598 }
3599
3600 // More lower-level change function, handling only a single document
3601 // (not linked ones).
3602 function makeChangeSingleDoc(doc, change, selAfter, spans) {
3603 if (doc.cm && !doc.cm.curOp)
3604 return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
3605
3606 if (change.to.line < doc.first) {
3607 shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
3608 return;
3609 }
3610 if (change.from.line > doc.lastLine()) return;
3611
3612 // Clip the change to the size of this doc
3613 if (change.from.line < doc.first) {
3614 var shift = change.text.length - 1 - (doc.first - change.from.line);
3615 shiftDoc(doc, shift);
3616 change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
3617 text: [lst(change.text)], origin: change.origin};
3618 }
3619 var last = doc.lastLine();
3620 if (change.to.line > last) {
3621 change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
3622 text: [change.text[0]], origin: change.origin};
3623 }
3624
3625 change.removed = getBetween(doc, change.from, change.to);
3626
3627 if (!selAfter) selAfter = computeSelAfterChange(doc, change);
3628 if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
3629 else updateDoc(doc, change, spans);
3630 setSelectionNoUndo(doc, selAfter, sel_dontScroll);
3631 }
3632
3633 // Handle the interaction of a change to a document with the editor
3634 // that this document is part of.
3635 function makeChangeSingleDocInEditor(cm, change, spans) {
3636 var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
3637
3638 var recomputeMaxLength = false, checkWidthStart = from.line;
3639 if (!cm.options.lineWrapping) {
3640 checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
3641 doc.iter(checkWidthStart, to.line + 1, function(line) {
3642 if (line == display.maxLine) {
3643 recomputeMaxLength = true;
3644 return true;
3645 }
3646 });
3647 }
3648
3649 if (doc.sel.contains(change.from, change.to) > -1)
3650 signalCursorActivity(cm);
3651
3652 updateDoc(doc, change, spans, estimateHeight(cm));
3653
3654 if (!cm.options.lineWrapping) {
3655 doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
3656 var len = lineLength(line);
3657 if (len > display.maxLineLength) {
3658 display.maxLine = line;
3659 display.maxLineLength = len;
3660 display.maxLineChanged = true;
3661 recomputeMaxLength = false;
3662 }
3663 });
3664 if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
3665 }
3666
3667 // Adjust frontier, schedule worker
3668 doc.frontier = Math.min(doc.frontier, from.line);
3669 startWorker(cm, 400);
3670
3671 var lendiff = change.text.length - (to.line - from.line) - 1;
3672 // Remember that these lines changed, for updating the display
3673 if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
3674 regLineChange(cm, from.line, "text");
3675 else
3676 regChange(cm, from.line, to.line + 1, lendiff);
3677
3678 var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
3679 if (changeHandler || changesHandler) {
3680 var obj = {
3681 from: from, to: to,
3682 text: change.text,
3683 removed: change.removed,
3684 origin: change.origin
3685 };
3686 if (changeHandler) signalLater(cm, "change", cm, obj);
3687 if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
3688 }
3689 cm.display.selForContextMenu = null;
3690 }
3691
3692 function replaceRange(doc, code, from, to, origin) {
3693 if (!to) to = from;
3694 if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
3695 if (typeof code == "string") code = splitLines(code);
3696 makeChange(doc, {from: from, to: to, text: code, origin: origin});
3697 }
3698
3699 // SCROLLING THINGS INTO VIEW
3700
3701 // If an editor sits on the top or bottom of the window, partially
3702 // scrolled out of view, this ensures that the cursor is visible.
3703 function maybeScrollWindow(cm, coords) {
3704 var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
3705 if (coords.top + box.top < 0) doScroll = true;
3706 else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
3707 if (doScroll != null && !phantom) {
3708 var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
3709 (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
3710 (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
3711 coords.left + "px; width: 2px;");
3712 cm.display.lineSpace.appendChild(scrollNode);
3713 scrollNode.scrollIntoView(doScroll);
3714 cm.display.lineSpace.removeChild(scrollNode);
3715 }
3716 }
3717
3718 // Scroll a given position into view (immediately), verifying that
3719 // it actually became visible (as line heights are accurately
3720 // measured, the position of something may 'drift' during drawing).
3721 function scrollPosIntoView(cm, pos, end, margin) {
3722 if (margin == null) margin = 0;
3723 for (var limit = 0; limit < 5; limit++) {
3724 var changed = false, coords = cursorCoords(cm, pos);
3725 var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
3726 var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
3727 Math.min(coords.top, endCoords.top) - margin,
3728 Math.max(coords.left, endCoords.left),
3729 Math.max(coords.bottom, endCoords.bottom) + margin);
3730 var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
3731 if (scrollPos.scrollTop != null) {
3732 setScrollTop(cm, scrollPos.scrollTop);
3733 if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
3734 }
3735 if (scrollPos.scrollLeft != null) {
3736 setScrollLeft(cm, scrollPos.scrollLeft);
3737 if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
3738 }
3739 if (!changed) return coords;
3740 }
3741 }
3742
3743 // Scroll a given set of coordinates into view (immediately).
3744 function scrollIntoView(cm, x1, y1, x2, y2) {
3745 var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
3746 if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
3747 if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
3748 }
3749
3750 // Calculate a new scroll position needed to scroll the given
3751 // rectangle into view. Returns an object with scrollTop and
3752 // scrollLeft properties. When these are undefined, the
3753 // vertical/horizontal position does not need to be adjusted.
3754 function calculateScrollPos(cm, x1, y1, x2, y2) {
3755 var display = cm.display, snapMargin = textHeight(cm.display);
3756 if (y1 < 0) y1 = 0;
3757 var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
3758 var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
3759 if (y2 - y1 > screen) y2 = y1 + screen;
3760 var docBottom = cm.doc.height + paddingVert(display);
3761 var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
3762 if (y1 < screentop) {
3763 result.scrollTop = atTop ? 0 : y1;
3764 } else if (y2 > screentop + screen) {
3765 var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
3766 if (newTop != screentop) result.scrollTop = newTop;
3767 }
3768
3769 var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
3770 var screenw = display.scroller.clientWidth - scrollerCutOff - display.gutters.offsetWidth;
3771 var tooWide = x2 - x1 > screenw;
3772 if (tooWide) x2 = x1 + screenw;
3773 if (x1 < 10)
3774 result.scrollLeft = 0;
3775 else if (x1 < screenleft)
3776 result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
3777 else if (x2 > screenw + screenleft - 3)
3778 result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
3779
3780 return result;
3781 }
3782
3783 // Store a relative adjustment to the scroll position in the current
3784 // operation (to be applied when the operation finishes).
3785 function addToScrollPos(cm, left, top) {
3786 if (left != null || top != null) resolveScrollToPos(cm);
3787 if (left != null)
3788 cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
3789 if (top != null)
3790 cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
3791 }
3792
3793 // Make sure that at the end of the operation the current cursor is
3794 // shown.
3795 function ensureCursorVisible(cm) {
3796 resolveScrollToPos(cm);
3797 var cur = cm.getCursor(), from = cur, to = cur;
3798 if (!cm.options.lineWrapping) {
3799 from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
3800 to = Pos(cur.line, cur.ch + 1);
3801 }
3802 cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
3803 }
3804
3805 // When an operation has its scrollToPos property set, and another
3806 // scroll action is applied before the end of the operation, this
3807 // 'simulates' scrolling that position into view in a cheap way, so
3808 // that the effect of intermediate scroll commands is not ignored.
3809 function resolveScrollToPos(cm) {
3810 var range = cm.curOp.scrollToPos;
3811 if (range) {
3812 cm.curOp.scrollToPos = null;
3813 var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
3814 var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
3815 Math.min(from.top, to.top) - range.margin,
3816 Math.max(from.right, to.right),
3817 Math.max(from.bottom, to.bottom) + range.margin);
3818 cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
3819 }
3820 }
3821
3822 // API UTILITIES
3823
3824 // Indent the given line. The how parameter can be "smart",
3825 // "add"/null, "subtract", or "prev". When aggressive is false
3826 // (typically set to true for forced single-line indents), empty
3827 // lines are not indented, and places where the mode returns Pass
3828 // are left alone.
3829 function indentLine(cm, n, how, aggressive) {
3830 var doc = cm.doc, state;
3831 if (how == null) how = "add";
3832 if (how == "smart") {
3833 // Fall back to "prev" when the mode doesn't have an indentation
3834 // method.
3835 if (!doc.mode.indent) how = "prev";
3836 else state = getStateBefore(cm, n);
3837 }
3838
3839 var tabSize = cm.options.tabSize;
3840 var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
3841 if (line.stateAfter) line.stateAfter = null;
3842 var curSpaceString = line.text.match(/^\s*/)[0], indentation;
3843 if (!aggressive && !/\S/.test(line.text)) {
3844 indentation = 0;
3845 how = "not";
3846 } else if (how == "smart") {
3847 indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
3848 if (indentation == Pass || indentation > 150) {
3849 if (!aggressive) return;
3850 how = "prev";
3851 }
3852 }
3853 if (how == "prev") {
3854 if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
3855 else indentation = 0;
3856 } else if (how == "add") {
3857 indentation = curSpace + cm.options.indentUnit;
3858 } else if (how == "subtract") {
3859 indentation = curSpace - cm.options.indentUnit;
3860 } else if (typeof how == "number") {
3861 indentation = curSpace + how;
3862 }
3863 indentation = Math.max(0, indentation);
3864
3865 var indentString = "", pos = 0;
3866 if (cm.options.indentWithTabs)
3867 for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
3868 if (pos < indentation) indentString += spaceStr(indentation - pos);
3869
3870 if (indentString != curSpaceString) {
3871 replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
3872 } else {
3873 // Ensure that, if the cursor was in the whitespace at the start
3874 // of the line, it is moved to the end of that space.
3875 for (var i = 0; i < doc.sel.ranges.length; i++) {
3876 var range = doc.sel.ranges[i];
3877 if (range.head.line == n && range.head.ch < curSpaceString.length) {
3878 var pos = Pos(n, curSpaceString.length);
3879 replaceOneSelection(doc, i, new Range(pos, pos));
3880 break;
3881 }
3882 }
3883 }
3884 line.stateAfter = null;
3885 }
3886
3887 // Utility for applying a change to a line by handle or number,
3888 // returning the number and optionally registering the line as
3889 // changed.
3890 function changeLine(doc, handle, changeType, op) {
3891 var no = handle, line = handle;
3892 if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
3893 else no = lineNo(handle);
3894 if (no == null) return null;
3895 if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);
3896 return line;
3897 }
3898
3899 // Helper for deleting text near the selection(s), used to implement
3900 // backspace, delete, and similar functionality.
3901 function deleteNearSelection(cm, compute) {
3902 var ranges = cm.doc.sel.ranges, kill = [];
3903 // Build up a set of ranges to kill first, merging overlapping
3904 // ranges.
3905 for (var i = 0; i < ranges.length; i++) {
3906 var toKill = compute(ranges[i]);
3907 while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
3908 var replaced = kill.pop();
3909 if (cmp(replaced.from, toKill.from) < 0) {
3910 toKill.from = replaced.from;
3911 break;
3912 }
3913 }
3914 kill.push(toKill);
3915 }
3916 // Next, remove those actual ranges.
3917 runInOp(cm, function() {
3918 for (var i = kill.length - 1; i >= 0; i--)
3919 replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
3920 ensureCursorVisible(cm);
3921 });
3922 }
3923
3924 // Used for horizontal relative motion. Dir is -1 or 1 (left or
3925 // right), unit can be "char", "column" (like char, but doesn't
3926 // cross line boundaries), "word" (across next word), or "group" (to
3927 // the start of next group of word or non-word-non-whitespace
3928 // chars). The visually param controls whether, in right-to-left
3929 // text, direction 1 means to move towards the next index in the
3930 // string, or towards the character to the right of the current
3931 // position. The resulting position will have a hitSide=true
3932 // property if it reached the end of the document.
3933 function findPosH(doc, pos, dir, unit, visually) {
3934 var line = pos.line, ch = pos.ch, origDir = dir;
3935 var lineObj = getLine(doc, line);
3936 var possible = true;
3937 function findNextLine() {
3938 var l = line + dir;
3939 if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
3940 line = l;
3941 return lineObj = getLine(doc, l);
3942 }
3943 function moveOnce(boundToLine) {
3944 var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
3945 if (next == null) {
3946 if (!boundToLine && findNextLine()) {
3947 if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
3948 else ch = dir < 0 ? lineObj.text.length : 0;
3949 } else return (possible = false);
3950 } else ch = next;
3951 return true;
3952 }
3953
3954 if (unit == "char") moveOnce();
3955 else if (unit == "column") moveOnce(true);
3956 else if (unit == "word" || unit == "group") {
3957 var sawType = null, group = unit == "group";
3958 var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
3959 for (var first = true;; first = false) {
3960 if (dir < 0 && !moveOnce(!first)) break;
3961 var cur = lineObj.text.charAt(ch) || "\n";
3962 var type = isWordChar(cur, helper) ? "w"
3963 : group && cur == "\n" ? "n"
3964 : !group || /\s/.test(cur) ? null
3965 : "p";
3966 if (group && !first && !type) type = "s";
3967 if (sawType && sawType != type) {
3968 if (dir < 0) {dir = 1; moveOnce();}
3969 break;
3970 }
3971
3972 if (type) sawType = type;
3973 if (dir > 0 && !moveOnce(!first)) break;
3974 }
3975 }
3976 var result = skipAtomic(doc, Pos(line, ch), origDir, true);
3977 if (!possible) result.hitSide = true;
3978 return result;
3979 }
3980
3981 // For relative vertical movement. Dir may be -1 or 1. Unit can be
3982 // "page" or "line". The resulting position will have a hitSide=true
3983 // property if it reached the end of the document.
3984 function findPosV(cm, pos, dir, unit) {
3985 var doc = cm.doc, x = pos.left, y;
3986 if (unit == "page") {
3987 var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
3988 y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
3989 } else if (unit == "line") {
3990 y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
3991 }
3992 for (;;) {
3993 var target = coordsChar(cm, x, y);
3994 if (!target.outside) break;
3995 if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
3996 y += dir * 5;
3997 }
3998 return target;
3999 }
4000
4001 // EDITOR METHODS
4002
4003 // The publicly visible API. Note that methodOp(f) means
4004 // 'wrap f in an operation, performed on its `this` parameter'.
4005
4006 // This is not the complete set of editor methods. Most of the
4007 // methods defined on the Doc type are also injected into
4008 // CodeMirror.prototype, for backwards compatibility and
4009 // convenience.
4010
4011 CodeMirror.prototype = {
4012 constructor: CodeMirror,
4013 focus: function(){window.focus(); focusInput(this); fastPoll(this);},
4014
4015 setOption: function(option, value) {
4016 var options = this.options, old = options[option];
4017 if (options[option] == value && option != "mode") return;
4018 options[option] = value;
4019 if (optionHandlers.hasOwnProperty(option))
4020 operation(this, optionHandlers[option])(this, value, old);
4021 },
4022
4023 getOption: function(option) {return this.options[option];},
4024 getDoc: function() {return this.doc;},
4025
4026 addKeyMap: function(map, bottom) {
4027 this.state.keyMaps[bottom ? "push" : "unshift"](map);
4028 },
4029 removeKeyMap: function(map) {
4030 var maps = this.state.keyMaps;
4031 for (var i = 0; i < maps.length; ++i)
4032 if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
4033 maps.splice(i, 1);
4034 return true;
4035 }
4036 },
4037
4038 addOverlay: methodOp(function(spec, options) {
4039 var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
4040 if (mode.startState) throw new Error("Overlays may not be stateful.");
4041 this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
4042 this.state.modeGen++;
4043 regChange(this);
4044 }),
4045 removeOverlay: methodOp(function(spec) {
4046 var overlays = this.state.overlays;
4047 for (var i = 0; i < overlays.length; ++i) {
4048 var cur = overlays[i].modeSpec;
4049 if (cur == spec || typeof spec == "string" && cur.name == spec) {
4050 overlays.splice(i, 1);
4051 this.state.modeGen++;
4052 regChange(this);
4053 return;
4054 }
4055 }
4056 }),
4057
4058 indentLine: methodOp(function(n, dir, aggressive) {
4059 if (typeof dir != "string" && typeof dir != "number") {
4060 if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
4061 else dir = dir ? "add" : "subtract";
4062 }
4063 if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
4064 }),
4065 indentSelection: methodOp(function(how) {
4066 var ranges = this.doc.sel.ranges, end = -1;
4067 for (var i = 0; i < ranges.length; i++) {
4068 var range = ranges[i];
4069 if (!range.empty()) {
4070 var from = range.from(), to = range.to();
4071 var start = Math.max(end, from.line);
4072 end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
4073 for (var j = start; j < end; ++j)
4074 indentLine(this, j, how);
4075 var newRanges = this.doc.sel.ranges;
4076 if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
4077 replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
4078 } else if (range.head.line > end) {
4079 indentLine(this, range.head.line, how, true);
4080 end = range.head.line;
4081 if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
4082 }
4083 }
4084 }),
4085
4086 // Fetch the parser token for a given character. Useful for hacks
4087 // that want to inspect the mode state (say, for completion).
4088 getTokenAt: function(pos, precise) {
4089 var doc = this.doc;
4090 pos = clipPos(doc, pos);
4091 var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
4092 var line = getLine(doc, pos.line);
4093 var stream = new StringStream(line.text, this.options.tabSize);
4094 while (stream.pos < pos.ch && !stream.eol()) {
4095 stream.start = stream.pos;
4096 var style = readToken(mode, stream, state);
4097 }
4098 return {start: stream.start,
4099 end: stream.pos,
4100 string: stream.current(),
4101 type: style || null,
4102 state: state};
4103 },
4104
4105 getTokenTypeAt: function(pos) {
4106 pos = clipPos(this.doc, pos);
4107 var styles = getLineStyles(this, getLine(this.doc, pos.line));
4108 var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
4109 var type;
4110 if (ch == 0) type = styles[2];
4111 else for (;;) {
4112 var mid = (before + after) >> 1;
4113 if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
4114 else if (styles[mid * 2 + 1] < ch) before = mid + 1;
4115 else { type = styles[mid * 2 + 2]; break; }
4116 }
4117 var cut = type ? type.indexOf("cm-overlay ") : -1;
4118 return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
4119 },
4120
4121 getModeAt: function(pos) {
4122 var mode = this.doc.mode;
4123 if (!mode.innerMode) return mode;
4124 return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
4125 },
4126
4127 getHelper: function(pos, type) {
4128 return this.getHelpers(pos, type)[0];
4129 },
4130
4131 getHelpers: function(pos, type) {
4132 var found = [];
4133 if (!helpers.hasOwnProperty(type)) return helpers;
4134 var help = helpers[type], mode = this.getModeAt(pos);
4135 if (typeof mode[type] == "string") {
4136 if (help[mode[type]]) found.push(help[mode[type]]);
4137 } else if (mode[type]) {
4138 for (var i = 0; i < mode[type].length; i++) {
4139 var val = help[mode[type][i]];
4140 if (val) found.push(val);
4141 }
4142 } else if (mode.helperType && help[mode.helperType]) {
4143 found.push(help[mode.helperType]);
4144 } else if (help[mode.name]) {
4145 found.push(help[mode.name]);
4146 }
4147 for (var i = 0; i < help._global.length; i++) {
4148 var cur = help._global[i];
4149 if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
4150 found.push(cur.val);
4151 }
4152 return found;
4153 },
4154
4155 getStateAfter: function(line, precise) {
4156 var doc = this.doc;
4157 line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
4158 return getStateBefore(this, line + 1, precise);
4159 },
4160
4161 cursorCoords: function(start, mode) {
4162 var pos, range = this.doc.sel.primary();
4163 if (start == null) pos = range.head;
4164 else if (typeof start == "object") pos = clipPos(this.doc, start);
4165 else pos = start ? range.from() : range.to();
4166 return cursorCoords(this, pos, mode || "page");
4167 },
4168
4169 charCoords: function(pos, mode) {
4170 return charCoords(this, clipPos(this.doc, pos), mode || "page");
4171 },
4172
4173 coordsChar: function(coords, mode) {
4174 coords = fromCoordSystem(this, coords, mode || "page");
4175 return coordsChar(this, coords.left, coords.top);
4176 },
4177
4178 lineAtHeight: function(height, mode) {
4179 height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
4180 return lineAtHeight(this.doc, height + this.display.viewOffset);
4181 },
4182 heightAtLine: function(line, mode) {
4183 var end = false, last = this.doc.first + this.doc.size - 1;
4184 if (line < this.doc.first) line = this.doc.first;
4185 else if (line > last) { line = last; end = true; }
4186 var lineObj = getLine(this.doc, line);
4187 return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
4188 (end ? this.doc.height - heightAtLine(lineObj) : 0);
4189 },
4190
4191 defaultTextHeight: function() { return textHeight(this.display); },
4192 defaultCharWidth: function() { return charWidth(this.display); },
4193
4194 setGutterMarker: methodOp(function(line, gutterID, value) {
4195 return changeLine(this.doc, line, "gutter", function(line) {
4196 var markers = line.gutterMarkers || (line.gutterMarkers = {});
4197 markers[gutterID] = value;
4198 if (!value && isEmpty(markers)) line.gutterMarkers = null;
4199 return true;
4200 });
4201 }),
4202
4203 clearGutter: methodOp(function(gutterID) {
4204 var cm = this, doc = cm.doc, i = doc.first;
4205 doc.iter(function(line) {
4206 if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
4207 line.gutterMarkers[gutterID] = null;
4208 regLineChange(cm, i, "gutter");
4209 if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
4210 }
4211 ++i;
4212 });
4213 }),
4214
4215 addLineWidget: methodOp(function(handle, node, options) {
4216 return addLineWidget(this, handle, node, options);
4217 }),
4218
4219 removeLineWidget: function(widget) { widget.clear(); },
4220
4221 lineInfo: function(line) {
4222 if (typeof line == "number") {
4223 if (!isLine(this.doc, line)) return null;
4224 var n = line;
4225 line = getLine(this.doc, line);
4226 if (!line) return null;
4227 } else {
4228 var n = lineNo(line);
4229 if (n == null) return null;
4230 }
4231 return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
4232 textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
4233 widgets: line.widgets};
4234 },
4235
4236 getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
4237
4238 addWidget: function(pos, node, scroll, vert, horiz) {
4239 var display = this.display;
4240 pos = cursorCoords(this, clipPos(this.doc, pos));
4241 var top = pos.bottom, left = pos.left;
4242 node.style.position = "absolute";
4243 display.sizer.appendChild(node);
4244 if (vert == "over") {
4245 top = pos.top;
4246 } else if (vert == "above" || vert == "near") {
4247 var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
4248 hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
4249 // Default to positioning above (if specified and possible); otherwise default to positioning below
4250 if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
4251 top = pos.top - node.offsetHeight;
4252 else if (pos.bottom + node.offsetHeight <= vspace)
4253 top = pos.bottom;
4254 if (left + node.offsetWidth > hspace)
4255 left = hspace - node.offsetWidth;
4256 }
4257 node.style.top = top + "px";
4258 node.style.left = node.style.right = "";
4259 if (horiz == "right") {
4260 left = display.sizer.clientWidth - node.offsetWidth;
4261 node.style.right = "0px";
4262 } else {
4263 if (horiz == "left") left = 0;
4264 else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
4265 node.style.left = left + "px";
4266 }
4267 if (scroll)
4268 scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
4269 },
4270
4271 triggerOnKeyDown: methodOp(onKeyDown),
4272 triggerOnKeyPress: methodOp(onKeyPress),
4273 triggerOnKeyUp: onKeyUp,
4274
4275 execCommand: function(cmd) {
4276 if (commands.hasOwnProperty(cmd))
4277 return commands[cmd](this);
4278 },
4279
4280 findPosH: function(from, amount, unit, visually) {
4281 var dir = 1;
4282 if (amount < 0) { dir = -1; amount = -amount; }
4283 for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
4284 cur = findPosH(this.doc, cur, dir, unit, visually);
4285 if (cur.hitSide) break;
4286 }
4287 return cur;
4288 },
4289
4290 moveH: methodOp(function(dir, unit) {
4291 var cm = this;
4292 cm.extendSelectionsBy(function(range) {
4293 if (cm.display.shift || cm.doc.extend || range.empty())
4294 return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
4295 else
4296 return dir < 0 ? range.from() : range.to();
4297 }, sel_move);
4298 }),
4299
4300 deleteH: methodOp(function(dir, unit) {
4301 var sel = this.doc.sel, doc = this.doc;
4302 if (sel.somethingSelected())
4303 doc.replaceSelection("", null, "+delete");
4304 else
4305 deleteNearSelection(this, function(range) {
4306 var other = findPosH(doc, range.head, dir, unit, false);
4307 return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
4308 });
4309 }),
4310
4311 findPosV: function(from, amount, unit, goalColumn) {
4312 var dir = 1, x = goalColumn;
4313 if (amount < 0) { dir = -1; amount = -amount; }
4314 for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
4315 var coords = cursorCoords(this, cur, "div");
4316 if (x == null) x = coords.left;
4317 else coords.left = x;
4318 cur = findPosV(this, coords, dir, unit);
4319 if (cur.hitSide) break;
4320 }
4321 return cur;
4322 },
4323
4324 moveV: methodOp(function(dir, unit) {
4325 var cm = this, doc = this.doc, goals = [];
4326 var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
4327 doc.extendSelectionsBy(function(range) {
4328 if (collapse)
4329 return dir < 0 ? range.from() : range.to();
4330 var headPos = cursorCoords(cm, range.head, "div");
4331 if (range.goalColumn != null) headPos.left = range.goalColumn;
4332 goals.push(headPos.left);
4333 var pos = findPosV(cm, headPos, dir, unit);
4334 if (unit == "page" && range == doc.sel.primary())
4335 addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
4336 return pos;
4337 }, sel_move);
4338 if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
4339 doc.sel.ranges[i].goalColumn = goals[i];
4340 }),
4341
4342 // Find the word at the given position (as returned by coordsChar).
4343 findWordAt: function(pos) {
4344 var doc = this.doc, line = getLine(doc, pos.line).text;
4345 var start = pos.ch, end = pos.ch;
4346 if (line) {
4347 var helper = this.getHelper(pos, "wordChars");
4348 if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
4349 var startChar = line.charAt(start);
4350 var check = isWordChar(startChar, helper)
4351 ? function(ch) { return isWordChar(ch, helper); }
4352 : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
4353 : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
4354 while (start > 0 && check(line.charAt(start - 1))) --start;
4355 while (end < line.length && check(line.charAt(end))) ++end;
4356 }
4357 return new Range(Pos(pos.line, start), Pos(pos.line, end));
4358 },
4359
4360 toggleOverwrite: function(value) {
4361 if (value != null && value == this.state.overwrite) return;
4362 if (this.state.overwrite = !this.state.overwrite)
4363 addClass(this.display.cursorDiv, "CodeMirror-overwrite");
4364 else
4365 rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
4366
4367 signal(this, "overwriteToggle", this, this.state.overwrite);
4368 },
4369 hasFocus: function() { return activeElt() == this.display.input; },
4370
4371 scrollTo: methodOp(function(x, y) {
4372 if (x != null || y != null) resolveScrollToPos(this);
4373 if (x != null) this.curOp.scrollLeft = x;
4374 if (y != null) this.curOp.scrollTop = y;
4375 }),
4376 getScrollInfo: function() {
4377 var scroller = this.display.scroller, co = scrollerCutOff;
4378 return {left: scroller.scrollLeft, top: scroller.scrollTop,
4379 height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
4380 clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
4381 },
4382
4383 scrollIntoView: methodOp(function(range, margin) {
4384 if (range == null) {
4385 range = {from: this.doc.sel.primary().head, to: null};
4386 if (margin == null) margin = this.options.cursorScrollMargin;
4387 } else if (typeof range == "number") {
4388 range = {from: Pos(range, 0), to: null};
4389 } else if (range.from == null) {
4390 range = {from: range, to: null};
4391 }
4392 if (!range.to) range.to = range.from;
4393 range.margin = margin || 0;
4394
4395 if (range.from.line != null) {
4396 resolveScrollToPos(this);
4397 this.curOp.scrollToPos = range;
4398 } else {
4399 var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
4400 Math.min(range.from.top, range.to.top) - range.margin,
4401 Math.max(range.from.right, range.to.right),
4402 Math.max(range.from.bottom, range.to.bottom) + range.margin);
4403 this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
4404 }
4405 }),
4406
4407 setSize: methodOp(function(width, height) {
4408 var cm = this;
4409 function interpret(val) {
4410 return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
4411 }
4412 if (width != null) cm.display.wrapper.style.width = interpret(width);
4413 if (height != null) cm.display.wrapper.style.height = interpret(height);
4414 if (cm.options.lineWrapping) clearLineMeasurementCache(this);
4415 var lineNo = cm.display.viewFrom;
4416 cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
4417 if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
4418 if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
4419 ++lineNo;
4420 });
4421 cm.curOp.forceUpdate = true;
4422 signal(cm, "refresh", this);
4423 }),
4424
4425 operation: function(f){return runInOp(this, f);},
4426
4427 refresh: methodOp(function() {
4428 var oldHeight = this.display.cachedTextHeight;
4429 regChange(this);
4430 this.curOp.forceUpdate = true;
4431 clearCaches(this);
4432 this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
4433 updateGutterSpace(this);
4434 if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
4435 estimateLineHeights(this);
4436 signal(this, "refresh", this);
4437 }),
4438
4439 swapDoc: methodOp(function(doc) {
4440 var old = this.doc;
4441 old.cm = null;
4442 attachDoc(this, doc);
4443 clearCaches(this);
4444 resetInput(this);
4445 this.scrollTo(doc.scrollLeft, doc.scrollTop);
4446 this.curOp.forceScroll = true;
4447 signalLater(this, "swapDoc", this, old);
4448 return old;
4449 }),
4450
4451 getInputField: function(){return this.display.input;},
4452 getWrapperElement: function(){return this.display.wrapper;},
4453 getScrollerElement: function(){return this.display.scroller;},
4454 getGutterElement: function(){return this.display.gutters;}
4455 };
4456 eventMixin(CodeMirror);
4457
4458 // OPTION DEFAULTS
4459
4460 // The default configuration options.
4461 var defaults = CodeMirror.defaults = {};
4462 // Functions to run when options are changed.
4463 var optionHandlers = CodeMirror.optionHandlers = {};
4464
4465 function option(name, deflt, handle, notOnInit) {
4466 CodeMirror.defaults[name] = deflt;
4467 if (handle) optionHandlers[name] =
4468 notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
4469 }
4470
4471 // Passed to option handlers when there is no old value.
4472 var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
4473
4474 // These two are, on init, called from the constructor because they
4475 // have to be initialized before the editor can start at all.
4476 option("value", "", function(cm, val) {
4477 cm.setValue(val);
4478 }, true);
4479 option("mode", null, function(cm, val) {
4480 cm.doc.modeOption = val;
4481 loadMode(cm);
4482 }, true);
4483
4484 option("indentUnit", 2, loadMode, true);
4485 option("indentWithTabs", false);
4486 option("smartIndent", true);
4487 option("tabSize", 4, function(cm) {
4488 resetModeState(cm);
4489 clearCaches(cm);
4490 regChange(cm);
4491 }, true);
4492 option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val) {
4493 cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
4494 cm.refresh();
4495 }, true);
4496 option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
4497 option("electricChars", true);
4498 option("rtlMoveVisually", !windows);
4499 option("wholeLineUpdateBefore", true);
4500
4501 option("theme", "default", function(cm) {
4502 themeChanged(cm);
4503 guttersChanged(cm);
4504 }, true);
4505 option("keyMap", "default", keyMapChanged);
4506 option("extraKeys", null);
4507
4508 option("lineWrapping", false, wrappingChanged, true);
4509 option("gutters", [], function(cm) {
4510 setGuttersForLineNumbers(cm.options);
4511 guttersChanged(cm);
4512 }, true);
4513 option("fixedGutter", true, function(cm, val) {
4514 cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
4515 cm.refresh();
4516 }, true);
4517 option("coverGutterNextToScrollbar", false, updateScrollbars, true);
4518 option("lineNumbers", false, function(cm) {
4519 setGuttersForLineNumbers(cm.options);
4520 guttersChanged(cm);
4521 }, true);
4522 option("firstLineNumber", 1, guttersChanged, true);
4523 option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
4524 option("showCursorWhenSelecting", false, updateSelection, true);
4525
4526 option("resetSelectionOnContextMenu", true);
4527
4528 option("readOnly", false, function(cm, val) {
4529 if (val == "nocursor") {
4530 onBlur(cm);
4531 cm.display.input.blur();
4532 cm.display.disabled = true;
4533 } else {
4534 cm.display.disabled = false;
4535 if (!val) resetInput(cm);
4536 }
4537 });
4538 option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
4539 option("dragDrop", true);
4540
4541 option("cursorBlinkRate", 530);
4542 option("cursorScrollMargin", 0);
4543 option("cursorHeight", 1, updateSelection, true);
4544 option("singleCursorHeightPerLine", true, updateSelection, true);
4545 option("workTime", 100);
4546 option("workDelay", 100);
4547 option("flattenSpans", true, resetModeState, true);
4548 option("addModeClass", false, resetModeState, true);
4549 option("pollInterval", 100);
4550 option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
4551 option("historyEventDelay", 1250);
4552 option("viewportMargin", 10, function(cm){cm.refresh();}, true);
4553 option("maxHighlightLength", 10000, resetModeState, true);
4554 option("moveInputWithCursor", true, function(cm, val) {
4555 if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
4556 });
4557
4558 option("tabindex", null, function(cm, val) {
4559 cm.display.input.tabIndex = val || "";
4560 });
4561 option("autofocus", null);
4562
4563 // MODE DEFINITION AND QUERYING
4564
4565 // Known modes, by name and by MIME
4566 var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
4567
4568 // Extra arguments are stored as the mode's dependencies, which is
4569 // used by (legacy) mechanisms like loadmode.js to automatically
4570 // load a mode. (Preferred mechanism is the require/define calls.)
4571 CodeMirror.defineMode = function(name, mode) {
4572 if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
4573 if (arguments.length > 2)
4574 mode.dependencies = Array.prototype.slice.call(arguments, 2);
4575 modes[name] = mode;
4576 };
4577
4578 CodeMirror.defineMIME = function(mime, spec) {
4579 mimeModes[mime] = spec;
4580 };
4581
4582 // Given a MIME type, a {name, ...options} config object, or a name
4583 // string, return a mode config object.
4584 CodeMirror.resolveMode = function(spec) {
4585 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
4586 spec = mimeModes[spec];
4587 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
4588 var found = mimeModes[spec.name];
4589 if (typeof found == "string") found = {name: found};
4590 spec = createObj(found, spec);
4591 spec.name = found.name;
4592 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
4593 return CodeMirror.resolveMode("application/xml");
4594 }
4595 if (typeof spec == "string") return {name: spec};
4596 else return spec || {name: "null"};
4597 };
4598
4599 // Given a mode spec (anything that resolveMode accepts), find and
4600 // initialize an actual mode object.
4601 CodeMirror.getMode = function(options, spec) {
4602 var spec = CodeMirror.resolveMode(spec);
4603 var mfactory = modes[spec.name];
4604 if (!mfactory) return CodeMirror.getMode(options, "text/plain");
4605 var modeObj = mfactory(options, spec);
4606 if (modeExtensions.hasOwnProperty(spec.name)) {
4607 var exts = modeExtensions[spec.name];
4608 for (var prop in exts) {
4609 if (!exts.hasOwnProperty(prop)) continue;
4610 if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
4611 modeObj[prop] = exts[prop];
4612 }
4613 }
4614 modeObj.name = spec.name;
4615 if (spec.helperType) modeObj.helperType = spec.helperType;
4616 if (spec.modeProps) for (var prop in spec.modeProps)
4617 modeObj[prop] = spec.modeProps[prop];
4618
4619 return modeObj;
4620 };
4621
4622 // Minimal default mode.
4623 CodeMirror.defineMode("null", function() {
4624 return {token: function(stream) {stream.skipToEnd();}};
4625 });
4626 CodeMirror.defineMIME("text/plain", "null");
4627
4628 // This can be used to attach properties to mode objects from
4629 // outside the actual mode definition.
4630 var modeExtensions = CodeMirror.modeExtensions = {};
4631 CodeMirror.extendMode = function(mode, properties) {
4632 var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
4633 copyObj(properties, exts);
4634 };
4635
4636 // EXTENSIONS
4637
4638 CodeMirror.defineExtension = function(name, func) {
4639 CodeMirror.prototype[name] = func;
4640 };
4641 CodeMirror.defineDocExtension = function(name, func) {
4642 Doc.prototype[name] = func;
4643 };
4644 CodeMirror.defineOption = option;
4645
4646 var initHooks = [];
4647 CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
4648
4649 var helpers = CodeMirror.helpers = {};
4650 CodeMirror.registerHelper = function(type, name, value) {
4651 if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
4652 helpers[type][name] = value;
4653 };
4654 CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
4655 CodeMirror.registerHelper(type, name, value);
4656 helpers[type]._global.push({pred: predicate, val: value});
4657 };
4658
4659 // MODE STATE HANDLING
4660
4661 // Utility functions for working with state. Exported because nested
4662 // modes need to do this for their inner modes.
4663
4664 var copyState = CodeMirror.copyState = function(mode, state) {
4665 if (state === true) return state;
4666 if (mode.copyState) return mode.copyState(state);
4667 var nstate = {};
4668 for (var n in state) {
4669 var val = state[n];
4670 if (val instanceof Array) val = val.concat([]);
4671 nstate[n] = val;
4672 }
4673 return nstate;
4674 };
4675
4676 var startState = CodeMirror.startState = function(mode, a1, a2) {
4677 return mode.startState ? mode.startState(a1, a2) : true;
4678 };
4679
4680 // Given a mode and a state (for that mode), find the inner mode and
4681 // state at the position that the state refers to.
4682 CodeMirror.innerMode = function(mode, state) {
4683 while (mode.innerMode) {
4684 var info = mode.innerMode(state);
4685 if (!info || info.mode == mode) break;
4686 state = info.state;
4687 mode = info.mode;
4688 }
4689 return info || {mode: mode, state: state};
4690 };
4691
4692 // STANDARD COMMANDS
4693
4694 // Commands are parameter-less actions that can be performed on an
4695 // editor, mostly used for keybindings.
4696 var commands = CodeMirror.commands = {
4697 selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
4698 singleSelection: function(cm) {
4699 cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
4700 },
4701 killLine: function(cm) {
4702 deleteNearSelection(cm, function(range) {
4703 if (range.empty()) {
4704 var len = getLine(cm.doc, range.head.line).text.length;
4705 if (range.head.ch == len && range.head.line < cm.lastLine())
4706 return {from: range.head, to: Pos(range.head.line + 1, 0)};
4707 else
4708 return {from: range.head, to: Pos(range.head.line, len)};
4709 } else {
4710 return {from: range.from(), to: range.to()};
4711 }
4712 });
4713 },
4714 deleteLine: function(cm) {
4715 deleteNearSelection(cm, function(range) {
4716 return {from: Pos(range.from().line, 0),
4717 to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
4718 });
4719 },
4720 delLineLeft: function(cm) {
4721 deleteNearSelection(cm, function(range) {
4722 return {from: Pos(range.from().line, 0), to: range.from()};
4723 });
4724 },
4725 delWrappedLineLeft: function(cm) {
4726 deleteNearSelection(cm, function(range) {
4727 var top = cm.charCoords(range.head, "div").top + 5;
4728 var leftPos = cm.coordsChar({left: 0, top: top}, "div");
4729 return {from: leftPos, to: range.from()};
4730 });
4731 },
4732 delWrappedLineRight: function(cm) {
4733 deleteNearSelection(cm, function(range) {
4734 var top = cm.charCoords(range.head, "div").top + 5;
4735 var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
4736 return {from: range.from(), to: rightPos };
4737 });
4738 },
4739 undo: function(cm) {cm.undo();},
4740 redo: function(cm) {cm.redo();},
4741 undoSelection: function(cm) {cm.undoSelection();},
4742 redoSelection: function(cm) {cm.redoSelection();},
4743 goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
4744 goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
4745 goLineStart: function(cm) {
4746 cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
4747 {origin: "+move", bias: 1});
4748 },
4749 goLineStartSmart: function(cm) {
4750 cm.extendSelectionsBy(function(range) {
4751 return lineStartSmart(cm, range.head);
4752 }, {origin: "+move", bias: 1});
4753 },
4754 goLineEnd: function(cm) {
4755 cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
4756 {origin: "+move", bias: -1});
4757 },
4758 goLineRight: function(cm) {
4759 cm.extendSelectionsBy(function(range) {
4760 var top = cm.charCoords(range.head, "div").top + 5;
4761 return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
4762 }, sel_move);
4763 },
4764 goLineLeft: function(cm) {
4765 cm.extendSelectionsBy(function(range) {
4766 var top = cm.charCoords(range.head, "div").top + 5;
4767 return cm.coordsChar({left: 0, top: top}, "div");
4768 }, sel_move);
4769 },
4770 goLineLeftSmart: function(cm) {
4771 cm.extendSelectionsBy(function(range) {
4772 var top = cm.charCoords(range.head, "div").top + 5;
4773 var pos = cm.coordsChar({left: 0, top: top}, "div");
4774 if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
4775 return pos;
4776 }, sel_move);
4777 },
4778 goLineUp: function(cm) {cm.moveV(-1, "line");},
4779 goLineDown: function(cm) {cm.moveV(1, "line");},
4780 goPageUp: function(cm) {cm.moveV(-1, "page");},
4781 goPageDown: function(cm) {cm.moveV(1, "page");},
4782 goCharLeft: function(cm) {cm.moveH(-1, "char");},
4783 goCharRight: function(cm) {cm.moveH(1, "char");},
4784 goColumnLeft: function(cm) {cm.moveH(-1, "column");},
4785 goColumnRight: function(cm) {cm.moveH(1, "column");},
4786 goWordLeft: function(cm) {cm.moveH(-1, "word");},
4787 goGroupRight: function(cm) {cm.moveH(1, "group");},
4788 goGroupLeft: function(cm) {cm.moveH(-1, "group");},
4789 goWordRight: function(cm) {cm.moveH(1, "word");},
4790 delCharBefore: function(cm) {cm.deleteH(-1, "char");},
4791 delCharAfter: function(cm) {cm.deleteH(1, "char");},
4792 delWordBefore: function(cm) {cm.deleteH(-1, "word");},
4793 delWordAfter: function(cm) {cm.deleteH(1, "word");},
4794 delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
4795 delGroupAfter: function(cm) {cm.deleteH(1, "group");},
4796 indentAuto: function(cm) {cm.indentSelection("smart");},
4797 indentMore: function(cm) {cm.indentSelection("add");},
4798 indentLess: function(cm) {cm.indentSelection("subtract");},
4799 insertTab: function(cm) {cm.replaceSelection("\t");},
4800 insertSoftTab: function(cm) {
4801 var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
4802 for (var i = 0; i < ranges.length; i++) {
4803 var pos = ranges[i].from();
4804 var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
4805 spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
4806 }
4807 cm.replaceSelections(spaces);
4808 },
4809 defaultTab: function(cm) {
4810 if (cm.somethingSelected()) cm.indentSelection("add");
4811 else cm.execCommand("insertTab");
4812 },
4813 transposeChars: function(cm) {
4814 runInOp(cm, function() {
4815 var ranges = cm.listSelections(), newSel = [];
4816 for (var i = 0; i < ranges.length; i++) {
4817 var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
4818 if (line) {
4819 if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
4820 if (cur.ch > 0) {
4821 cur = new Pos(cur.line, cur.ch + 1);
4822 cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
4823 Pos(cur.line, cur.ch - 2), cur, "+transpose");
4824 } else if (cur.line > cm.doc.first) {
4825 var prev = getLine(cm.doc, cur.line - 1).text;
4826 if (prev)
4827 cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
4828 Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
4829 }
4830 }
4831 newSel.push(new Range(cur, cur));
4832 }
4833 cm.setSelections(newSel);
4834 });
4835 },
4836 newlineAndIndent: function(cm) {
4837 runInOp(cm, function() {
4838 var len = cm.listSelections().length;
4839 for (var i = 0; i < len; i++) {
4840 var range = cm.listSelections()[i];
4841 cm.replaceRange("\n", range.anchor, range.head, "+input");
4842 cm.indentLine(range.from().line + 1, null, true);
4843 ensureCursorVisible(cm);
4844 }
4845 });
4846 },
4847 toggleOverwrite: function(cm) {cm.toggleOverwrite();}
4848 };
4849
4850 // STANDARD KEYMAPS
4851
4852 var keyMap = CodeMirror.keyMap = {};
4853 keyMap.basic = {
4854 "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
4855 "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
4856 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
4857 "Tab": "defaultTab", "Shift-Tab": "indentAuto",
4858 "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
4859 "Esc": "singleSelection"
4860 };
4861 // Note that the save and find-related commands aren't defined by
4862 // default. User code or addons can define them. Unknown commands
4863 // are simply ignored.
4864 keyMap.pcDefault = {
4865 "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
4866 "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
4867 "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
4868 "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
4869 "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
4870 "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
4871 "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
4872 fallthrough: "basic"
4873 };
4874 keyMap.macDefault = {
4875 "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
4876 "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
4877 "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
4878 "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
4879 "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
4880 "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
4881 "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
4882 fallthrough: ["basic", "emacsy"]
4883 };
4884 // Very basic readline/emacs-style bindings, which are standard on Mac.
4885 keyMap.emacsy = {
4886 "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
4887 "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
4888 "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
4889 "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
4890 };
4891 keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
4892
4893 // KEYMAP DISPATCH
4894
4895 function getKeyMap(val) {
4896 if (typeof val == "string") return keyMap[val];
4897 else return val;
4898 }
4899
4900 // Given an array of keymaps and a key name, call handle on any
4901 // bindings found, until that returns a truthy value, at which point
4902 // we consider the key handled. Implements things like binding a key
4903 // to false stopping further handling and keymap fallthrough.
4904 var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) {
4905 function lookup(map) {
4906 map = getKeyMap(map);
4907 var found = map[name];
4908 if (found === false) return "stop";
4909 if (found != null && handle(found)) return true;
4910 if (map.nofallthrough) return "stop";
4911
4912 var fallthrough = map.fallthrough;
4913 if (fallthrough == null) return false;
4914 if (Object.prototype.toString.call(fallthrough) != "[object Array]")
4915 return lookup(fallthrough);
4916 for (var i = 0; i < fallthrough.length; ++i) {
4917 var done = lookup(fallthrough[i]);
4918 if (done) return done;
4919 }
4920 return false;
4921 }
4922
4923 for (var i = 0; i < maps.length; ++i) {
4924 var done = lookup(maps[i]);
4925 if (done) return done != "stop";
4926 }
4927 };
4928
4929 // Modifier key presses don't count as 'real' key presses for the
4930 // purpose of keymap fallthrough.
4931 var isModifierKey = CodeMirror.isModifierKey = function(event) {
4932 var name = keyNames[event.keyCode];
4933 return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
4934 };
4935
4936 // Look up the name of a key as indicated by an event object.
4937 var keyName = CodeMirror.keyName = function(event, noShift) {
4938 if (presto && event.keyCode == 34 && event["char"]) return false;
4939 var name = keyNames[event.keyCode];
4940 if (name == null || event.altGraphKey) return false;
4941 if (event.altKey) name = "Alt-" + name;
4942 if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
4943 if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
4944 if (!noShift && event.shiftKey) name = "Shift-" + name;
4945 return name;
4946 };
4947
4948 // FROMTEXTAREA
4949
4950 CodeMirror.fromTextArea = function(textarea, options) {
4951 if (!options) options = {};
4952 options.value = textarea.value;
4953 if (!options.tabindex && textarea.tabindex)
4954 options.tabindex = textarea.tabindex;
4955 if (!options.placeholder && textarea.placeholder)
4956 options.placeholder = textarea.placeholder;
4957 // Set autofocus to true if this textarea is focused, or if it has
4958 // autofocus and no other element is focused.
4959 if (options.autofocus == null) {
4960 var hasFocus = activeElt();
4961 options.autofocus = hasFocus == textarea ||
4962 textarea.getAttribute("autofocus") != null && hasFocus == document.body;
4963 }
4964
4965 function save() {textarea.value = cm.getValue();}
4966 if (textarea.form) {
4967 on(textarea.form, "submit", save);
4968 // Deplorable hack to make the submit method do the right thing.
4969 if (!options.leaveSubmitMethodAlone) {
4970 var form = textarea.form, realSubmit = form.submit;
4971 try {
4972 var wrappedSubmit = form.submit = function() {
4973 save();
4974 form.submit = realSubmit;
4975 form.submit();
4976 form.submit = wrappedSubmit;
4977 };
4978 } catch(e) {}
4979 }
4980 }
4981
4982 textarea.style.display = "none";
4983 var cm = CodeMirror(function(node) {
4984 textarea.parentNode.insertBefore(node, textarea.nextSibling);
4985 }, options);
4986 cm.save = save;
4987 cm.getTextArea = function() { return textarea; };
4988 cm.toTextArea = function() {
4989 cm.toTextArea = isNaN; // Prevent this from being ran twice
4990 save();
4991 textarea.parentNode.removeChild(cm.getWrapperElement());
4992 textarea.style.display = "";
4993 if (textarea.form) {
4994 off(textarea.form, "submit", save);
4995 if (typeof textarea.form.submit == "function")
4996 textarea.form.submit = realSubmit;
4997 }
4998 };
4999 return cm;
5000 };
5001
5002 // STRING STREAM
5003
5004 // Fed to the mode parsers, provides helper functions to make
5005 // parsers more succinct.
5006
5007 var StringStream = CodeMirror.StringStream = function(string, tabSize) {
5008 this.pos = this.start = 0;
5009 this.string = string;
5010 this.tabSize = tabSize || 8;
5011 this.lastColumnPos = this.lastColumnValue = 0;
5012 this.lineStart = 0;
5013 };
5014
5015 StringStream.prototype = {
5016 eol: function() {return this.pos >= this.string.length;},
5017 sol: function() {return this.pos == this.lineStart;},
5018 peek: function() {return this.string.charAt(this.pos) || undefined;},
5019 next: function() {
5020 if (this.pos < this.string.length)
5021 return this.string.charAt(this.pos++);
5022 },
5023 eat: function(match) {
5024 var ch = this.string.charAt(this.pos);
5025 if (typeof match == "string") var ok = ch == match;
5026 else var ok = ch && (match.test ? match.test(ch) : match(ch));
5027 if (ok) {++this.pos; return ch;}
5028 },
5029 eatWhile: function(match) {
5030 var start = this.pos;
5031 while (this.eat(match)){}
5032 return this.pos > start;
5033 },
5034 eatSpace: function() {
5035 var start = this.pos;
5036 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
5037 return this.pos > start;
5038 },
5039 skipToEnd: function() {this.pos = this.string.length;},
5040 skipTo: function(ch) {
5041 var found = this.string.indexOf(ch, this.pos);
5042 if (found > -1) {this.pos = found; return true;}
5043 },
5044 backUp: function(n) {this.pos -= n;},
5045 column: function() {
5046 if (this.lastColumnPos < this.start) {
5047 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
5048 this.lastColumnPos = this.start;
5049 }
5050 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
5051 },
5052 indentation: function() {
5053 return countColumn(this.string, null, this.tabSize) -
5054 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
5055 },
5056 match: function(pattern, consume, caseInsensitive) {
5057 if (typeof pattern == "string") {
5058 var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
5059 var substr = this.string.substr(this.pos, pattern.length);
5060 if (cased(substr) == cased(pattern)) {
5061 if (consume !== false) this.pos += pattern.length;
5062 return true;
5063 }
5064 } else {
5065 var match = this.string.slice(this.pos).match(pattern);
5066 if (match && match.index > 0) return null;
5067 if (match && consume !== false) this.pos += match[0].length;
5068 return match;
5069 }
5070 },
5071 current: function(){return this.string.slice(this.start, this.pos);},
5072 hideFirstChars: function(n, inner) {
5073 this.lineStart += n;
5074 try { return inner(); }
5075 finally { this.lineStart -= n; }
5076 }
5077 };
5078
5079 // TEXTMARKERS
5080
5081 // Created with markText and setBookmark methods. A TextMarker is a
5082 // handle that can be used to clear or find a marked position in the
5083 // document. Line objects hold arrays (markedSpans) containing
5084 // {from, to, marker} object pointing to such marker objects, and
5085 // indicating that such a marker is present on that line. Multiple
5086 // lines may point to the same marker when it spans across lines.
5087 // The spans will have null for their from/to properties when the
5088 // marker continues beyond the start/end of the line. Markers have
5089 // links back to the lines they currently touch.
5090
5091 var TextMarker = CodeMirror.TextMarker = function(doc, type) {
5092 this.lines = [];
5093 this.type = type;
5094 this.doc = doc;
5095 };
5096 eventMixin(TextMarker);
5097
5098 // Clear the marker.
5099 TextMarker.prototype.clear = function() {
5100 if (this.explicitlyCleared) return;
5101 var cm = this.doc.cm, withOp = cm && !cm.curOp;
5102 if (withOp) startOperation(cm);
5103 if (hasHandler(this, "clear")) {
5104 var found = this.find();
5105 if (found) signalLater(this, "clear", found.from, found.to);
5106 }
5107 var min = null, max = null;
5108 for (var i = 0; i < this.lines.length; ++i) {
5109 var line = this.lines[i];
5110 var span = getMarkedSpanFor(line.markedSpans, this);
5111 if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
5112 else if (cm) {
5113 if (span.to != null) max = lineNo(line);
5114 if (span.from != null) min = lineNo(line);
5115 }
5116 line.markedSpans = removeMarkedSpan(line.markedSpans, span);
5117 if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
5118 updateLineHeight(line, textHeight(cm.display));
5119 }
5120 if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
5121 var visual = visualLine(this.lines[i]), len = lineLength(visual);
5122 if (len > cm.display.maxLineLength) {
5123 cm.display.maxLine = visual;
5124 cm.display.maxLineLength = len;
5125 cm.display.maxLineChanged = true;
5126 }
5127 }
5128
5129 if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
5130 this.lines.length = 0;
5131 this.explicitlyCleared = true;
5132 if (this.atomic && this.doc.cantEdit) {
5133 this.doc.cantEdit = false;
5134 if (cm) reCheckSelection(cm.doc);
5135 }
5136 if (cm) signalLater(cm, "markerCleared", cm, this);
5137 if (withOp) endOperation(cm);
5138 if (this.parent) this.parent.clear();
5139 };
5140
5141 // Find the position of the marker in the document. Returns a {from,
5142 // to} object by default. Side can be passed to get a specific side
5143 // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
5144 // Pos objects returned contain a line object, rather than a line
5145 // number (used to prevent looking up the same line twice).
5146 TextMarker.prototype.find = function(side, lineObj) {
5147 if (side == null && this.type == "bookmark") side = 1;
5148 var from, to;
5149 for (var i = 0; i < this.lines.length; ++i) {
5150 var line = this.lines[i];
5151 var span = getMarkedSpanFor(line.markedSpans, this);
5152 if (span.from != null) {
5153 from = Pos(lineObj ? line : lineNo(line), span.from);
5154 if (side == -1) return from;
5155 }
5156 if (span.to != null) {
5157 to = Pos(lineObj ? line : lineNo(line), span.to);
5158 if (side == 1) return to;
5159 }
5160 }
5161 return from && {from: from, to: to};
5162 };
5163
5164 // Signals that the marker's widget changed, and surrounding layout
5165 // should be recomputed.
5166 TextMarker.prototype.changed = function() {
5167 var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
5168 if (!pos || !cm) return;
5169 runInOp(cm, function() {
5170 var line = pos.line, lineN = lineNo(pos.line);
5171 var view = findViewForLine(cm, lineN);
5172 if (view) {
5173 clearLineMeasurementCacheFor(view);
5174 cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
5175 }
5176 cm.curOp.updateMaxLine = true;
5177 if (!lineIsHidden(widget.doc, line) && widget.height != null) {
5178 var oldHeight = widget.height;
5179 widget.height = null;
5180 var dHeight = widgetHeight(widget) - oldHeight;
5181 if (dHeight)
5182 updateLineHeight(line, line.height + dHeight);
5183 }
5184 });
5185 };
5186
5187 TextMarker.prototype.attachLine = function(line) {
5188 if (!this.lines.length && this.doc.cm) {
5189 var op = this.doc.cm.curOp;
5190 if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
5191 (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
5192 }
5193 this.lines.push(line);
5194 };
5195 TextMarker.prototype.detachLine = function(line) {
5196 this.lines.splice(indexOf(this.lines, line), 1);
5197 if (!this.lines.length && this.doc.cm) {
5198 var op = this.doc.cm.curOp;
5199 (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
5200 }
5201 };
5202
5203 // Collapsed markers have unique ids, in order to be able to order
5204 // them, which is needed for uniquely determining an outer marker
5205 // when they overlap (they may nest, but not partially overlap).
5206 var nextMarkerId = 0;
5207
5208 // Create a marker, wire it up to the right lines, and
5209 function markText(doc, from, to, options, type) {
5210 // Shared markers (across linked documents) are handled separately
5211 // (markTextShared will call out to this again, once per
5212 // document).
5213 if (options && options.shared) return markTextShared(doc, from, to, options, type);
5214 // Ensure we are in an operation.
5215 if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
5216
5217 var marker = new TextMarker(doc, type), diff = cmp(from, to);
5218 if (options) copyObj(options, marker, false);
5219 // Don't connect empty markers unless clearWhenEmpty is false
5220 if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
5221 return marker;
5222 if (marker.replacedWith) {
5223 // Showing up as a widget implies collapsed (widget replaces text)
5224 marker.collapsed = true;
5225 marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
5226 if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true;
5227 if (options.insertLeft) marker.widgetNode.insertLeft = true;
5228 }
5229 if (marker.collapsed) {
5230 if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
5231 from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
5232 throw new Error("Inserting collapsed marker partially overlapping an existing one");
5233 sawCollapsedSpans = true;
5234 }
5235
5236 if (marker.addToHistory)
5237 addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
5238
5239 var curLine = from.line, cm = doc.cm, updateMaxLine;
5240 doc.iter(curLine, to.line + 1, function(line) {
5241 if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
5242 updateMaxLine = true;
5243 if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
5244 addMarkedSpan(line, new MarkedSpan(marker,
5245 curLine == from.line ? from.ch : null,
5246 curLine == to.line ? to.ch : null));
5247 ++curLine;
5248 });
5249 // lineIsHidden depends on the presence of the spans, so needs a second pass
5250 if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
5251 if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
5252 });
5253
5254 if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
5255
5256 if (marker.readOnly) {
5257 sawReadOnlySpans = true;
5258 if (doc.history.done.length || doc.history.undone.length)
5259 doc.clearHistory();
5260 }
5261 if (marker.collapsed) {
5262 marker.id = ++nextMarkerId;
5263 marker.atomic = true;
5264 }
5265 if (cm) {
5266 // Sync editor state
5267 if (updateMaxLine) cm.curOp.updateMaxLine = true;
5268 if (marker.collapsed)
5269 regChange(cm, from.line, to.line + 1);
5270 else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
5271 for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
5272 if (marker.atomic) reCheckSelection(cm.doc);
5273 signalLater(cm, "markerAdded", cm, marker);
5274 }
5275 return marker;
5276 }
5277
5278 // SHARED TEXTMARKERS
5279
5280 // A shared marker spans multiple linked documents. It is
5281 // implemented as a meta-marker-object controlling multiple normal
5282 // markers.
5283 var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
5284 this.markers = markers;
5285 this.primary = primary;
5286 for (var i = 0; i < markers.length; ++i)
5287 markers[i].parent = this;
5288 };
5289 eventMixin(SharedTextMarker);
5290
5291 SharedTextMarker.prototype.clear = function() {
5292 if (this.explicitlyCleared) return;
5293 this.explicitlyCleared = true;
5294 for (var i = 0; i < this.markers.length; ++i)
5295 this.markers[i].clear();
5296 signalLater(this, "clear");
5297 };
5298 SharedTextMarker.prototype.find = function(side, lineObj) {
5299 return this.primary.find(side, lineObj);
5300 };
5301
5302 function markTextShared(doc, from, to, options, type) {
5303 options = copyObj(options);
5304 options.shared = false;
5305 var markers = [markText(doc, from, to, options, type)], primary = markers[0];
5306 var widget = options.widgetNode;
5307 linkedDocs(doc, function(doc) {
5308 if (widget) options.widgetNode = widget.cloneNode(true);
5309 markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
5310 for (var i = 0; i < doc.linked.length; ++i)
5311 if (doc.linked[i].isParent) return;
5312 primary = lst(markers);
5313 });
5314 return new SharedTextMarker(markers, primary);
5315 }
5316
5317 function findSharedMarkers(doc) {
5318 return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
5319 function(m) { return m.parent; });
5320 }
5321
5322 function copySharedMarkers(doc, markers) {
5323 for (var i = 0; i < markers.length; i++) {
5324 var marker = markers[i], pos = marker.find();
5325 var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
5326 if (cmp(mFrom, mTo)) {
5327 var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
5328 marker.markers.push(subMark);
5329 subMark.parent = marker;
5330 }
5331 }
5332 }
5333
5334 function detachSharedMarkers(markers) {
5335 for (var i = 0; i < markers.length; i++) {
5336 var marker = markers[i], linked = [marker.primary.doc];;
5337 linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
5338 for (var j = 0; j < marker.markers.length; j++) {
5339 var subMarker = marker.markers[j];
5340 if (indexOf(linked, subMarker.doc) == -1) {
5341 subMarker.parent = null;
5342 marker.markers.splice(j--, 1);
5343 }
5344 }
5345 }
5346 }
5347
5348 // TEXTMARKER SPANS
5349
5350 function MarkedSpan(marker, from, to) {
5351 this.marker = marker;
5352 this.from = from; this.to = to;
5353 }
5354
5355 // Search an array of spans for a span matching the given marker.
5356 function getMarkedSpanFor(spans, marker) {
5357 if (spans) for (var i = 0; i < spans.length; ++i) {
5358 var span = spans[i];
5359 if (span.marker == marker) return span;
5360 }
5361 }
5362 // Remove a span from an array, returning undefined if no spans are
5363 // left (we don't store arrays for lines without spans).
5364 function removeMarkedSpan(spans, span) {
5365 for (var r, i = 0; i < spans.length; ++i)
5366 if (spans[i] != span) (r || (r = [])).push(spans[i]);
5367 return r;
5368 }
5369 // Add a span to a line.
5370 function addMarkedSpan(line, span) {
5371 line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
5372 span.marker.attachLine(line);
5373 }
5374
5375 // Used for the algorithm that adjusts markers for a change in the
5376 // document. These functions cut an array of spans at a given
5377 // character position, returning an array of remaining chunks (or
5378 // undefined if nothing remains).
5379 function markedSpansBefore(old, startCh, isInsert) {
5380 if (old) for (var i = 0, nw; i < old.length; ++i) {
5381 var span = old[i], marker = span.marker;
5382 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
5383 if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
5384 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
5385 (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
5386 }
5387 }
5388 return nw;
5389 }
5390 function markedSpansAfter(old, endCh, isInsert) {
5391 if (old) for (var i = 0, nw; i < old.length; ++i) {
5392 var span = old[i], marker = span.marker;
5393 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
5394 if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
5395 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
5396 (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
5397 span.to == null ? null : span.to - endCh));
5398 }
5399 }
5400 return nw;
5401 }
5402
5403 // Given a change object, compute the new set of marker spans that
5404 // cover the line in which the change took place. Removes spans
5405 // entirely within the change, reconnects spans belonging to the
5406 // same marker that appear on both sides of the change, and cuts off
5407 // spans partially within the change. Returns an array of span
5408 // arrays with one element for each line in (after) the change.
5409 function stretchSpansOverChange(doc, change) {
5410 var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
5411 var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
5412 if (!oldFirst && !oldLast) return null;
5413
5414 var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
5415 // Get the spans that 'stick out' on both sides
5416 var first = markedSpansBefore(oldFirst, startCh, isInsert);
5417 var last = markedSpansAfter(oldLast, endCh, isInsert);
5418
5419 // Next, merge those two ends
5420 var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
5421 if (first) {
5422 // Fix up .to properties of first
5423 for (var i = 0; i < first.length; ++i) {
5424 var span = first[i];
5425 if (span.to == null) {
5426 var found = getMarkedSpanFor(last, span.marker);
5427 if (!found) span.to = startCh;
5428 else if (sameLine) span.to = found.to == null ? null : found.to + offset;
5429 }
5430 }
5431 }
5432 if (last) {
5433 // Fix up .from in last (or move them into first in case of sameLine)
5434 for (var i = 0; i < last.length; ++i) {
5435 var span = last[i];
5436 if (span.to != null) span.to += offset;
5437 if (span.from == null) {
5438 var found = getMarkedSpanFor(first, span.marker);
5439 if (!found) {
5440 span.from = offset;
5441 if (sameLine) (first || (first = [])).push(span);
5442 }
5443 } else {
5444 span.from += offset;
5445 if (sameLine) (first || (first = [])).push(span);
5446 }
5447 }
5448 }
5449 // Make sure we didn't create any zero-length spans
5450 if (first) first = clearEmptySpans(first);
5451 if (last && last != first) last = clearEmptySpans(last);
5452
5453 var newMarkers = [first];
5454 if (!sameLine) {
5455 // Fill gap with whole-line-spans
5456 var gap = change.text.length - 2, gapMarkers;
5457 if (gap > 0 && first)
5458 for (var i = 0; i < first.length; ++i)
5459 if (first[i].to == null)
5460 (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
5461 for (var i = 0; i < gap; ++i)
5462 newMarkers.push(gapMarkers);
5463 newMarkers.push(last);
5464 }
5465 return newMarkers;
5466 }
5467
5468 // Remove spans that are empty and don't have a clearWhenEmpty
5469 // option of false.
5470 function clearEmptySpans(spans) {
5471 for (var i = 0; i < spans.length; ++i) {
5472 var span = spans[i];
5473 if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
5474 spans.splice(i--, 1);
5475 }
5476 if (!spans.length) return null;
5477 return spans;
5478 }
5479
5480 // Used for un/re-doing changes from the history. Combines the
5481 // result of computing the existing spans with the set of spans that
5482 // existed in the history (so that deleting around a span and then
5483 // undoing brings back the span).
5484 function mergeOldSpans(doc, change) {
5485 var old = getOldSpans(doc, change);
5486 var stretched = stretchSpansOverChange(doc, change);
5487 if (!old) return stretched;
5488 if (!stretched) return old;
5489
5490 for (var i = 0; i < old.length; ++i) {
5491 var oldCur = old[i], stretchCur = stretched[i];
5492 if (oldCur && stretchCur) {
5493 spans: for (var j = 0; j < stretchCur.length; ++j) {
5494 var span = stretchCur[j];
5495 for (var k = 0; k < oldCur.length; ++k)
5496 if (oldCur[k].marker == span.marker) continue spans;
5497 oldCur.push(span);
5498 }
5499 } else if (stretchCur) {
5500 old[i] = stretchCur;
5501 }
5502 }
5503 return old;
5504 }
5505
5506 // Used to 'clip' out readOnly ranges when making a change.
5507 function removeReadOnlyRanges(doc, from, to) {
5508 var markers = null;
5509 doc.iter(from.line, to.line + 1, function(line) {
5510 if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
5511 var mark = line.markedSpans[i].marker;
5512 if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
5513 (markers || (markers = [])).push(mark);
5514 }
5515 });
5516 if (!markers) return null;
5517 var parts = [{from: from, to: to}];
5518 for (var i = 0; i < markers.length; ++i) {
5519 var mk = markers[i], m = mk.find(0);
5520 for (var j = 0; j < parts.length; ++j) {
5521 var p = parts[j];
5522 if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
5523 var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
5524 if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
5525 newParts.push({from: p.from, to: m.from});
5526 if (dto > 0 || !mk.inclusiveRight && !dto)
5527 newParts.push({from: m.to, to: p.to});
5528 parts.splice.apply(parts, newParts);
5529 j += newParts.length - 1;
5530 }
5531 }
5532 return parts;
5533 }
5534
5535 // Connect or disconnect spans from a line.
5536 function detachMarkedSpans(line) {
5537 var spans = line.markedSpans;
5538 if (!spans) return;
5539 for (var i = 0; i < spans.length; ++i)
5540 spans[i].marker.detachLine(line);
5541 line.markedSpans = null;
5542 }
5543 function attachMarkedSpans(line, spans) {
5544 if (!spans) return;
5545 for (var i = 0; i < spans.length; ++i)
5546 spans[i].marker.attachLine(line);
5547 line.markedSpans = spans;
5548 }
5549
5550 // Helpers used when computing which overlapping collapsed span
5551 // counts as the larger one.
5552 function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
5553 function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
5554
5555 // Returns a number indicating which of two overlapping collapsed
5556 // spans is larger (and thus includes the other). Falls back to
5557 // comparing ids when the spans cover exactly the same range.
5558 function compareCollapsedMarkers(a, b) {
5559 var lenDiff = a.lines.length - b.lines.length;
5560 if (lenDiff != 0) return lenDiff;
5561 var aPos = a.find(), bPos = b.find();
5562 var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
5563 if (fromCmp) return -fromCmp;
5564 var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
5565 if (toCmp) return toCmp;
5566 return b.id - a.id;
5567 }
5568
5569 // Find out whether a line ends or starts in a collapsed span. If
5570 // so, return the marker for that span.
5571 function collapsedSpanAtSide(line, start) {
5572 var sps = sawCollapsedSpans && line.markedSpans, found;
5573 if (sps) for (var sp, i = 0; i < sps.length; ++i) {
5574 sp = sps[i];
5575 if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
5576 (!found || compareCollapsedMarkers(found, sp.marker) < 0))
5577 found = sp.marker;
5578 }
5579 return found;
5580 }
5581 function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
5582 function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
5583
5584 // Test whether there exists a collapsed span that partially
5585 // overlaps (covers the start or end, but not both) of a new span.
5586 // Such overlap is not allowed.
5587 function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
5588 var line = getLine(doc, lineNo);
5589 var sps = sawCollapsedSpans && line.markedSpans;
5590 if (sps) for (var i = 0; i < sps.length; ++i) {
5591 var sp = sps[i];
5592 if (!sp.marker.collapsed) continue;
5593 var found = sp.marker.find(0);
5594 var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
5595 var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
5596 if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
5597 if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||
5598 fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))
5599 return true;
5600 }
5601 }
5602
5603 // A visual line is a line as drawn on the screen. Folding, for
5604 // example, can cause multiple logical lines to appear on the same
5605 // visual line. This finds the start of the visual line that the
5606 // given line is part of (usually that is the line itself).
5607 function visualLine(line) {
5608 var merged;
5609 while (merged = collapsedSpanAtStart(line))
5610 line = merged.find(-1, true).line;
5611 return line;
5612 }
5613
5614 // Returns an array of logical lines that continue the visual line
5615 // started by the argument, or undefined if there are no such lines.
5616 function visualLineContinued(line) {
5617 var merged, lines;
5618 while (merged = collapsedSpanAtEnd(line)) {
5619 line = merged.find(1, true).line;
5620 (lines || (lines = [])).push(line);
5621 }
5622 return lines;
5623 }
5624
5625 // Get the line number of the start of the visual line that the
5626 // given line number is part of.
5627 function visualLineNo(doc, lineN) {
5628 var line = getLine(doc, lineN), vis = visualLine(line);
5629 if (line == vis) return lineN;
5630 return lineNo(vis);
5631 }
5632 // Get the line number of the start of the next visual line after
5633 // the given line.
5634 function visualLineEndNo(doc, lineN) {
5635 if (lineN > doc.lastLine()) return lineN;
5636 var line = getLine(doc, lineN), merged;
5637 if (!lineIsHidden(doc, line)) return lineN;
5638 while (merged = collapsedSpanAtEnd(line))
5639 line = merged.find(1, true).line;
5640 return lineNo(line) + 1;
5641 }
5642
5643 // Compute whether a line is hidden. Lines count as hidden when they
5644 // are part of a visual line that starts with another line, or when
5645 // they are entirely covered by collapsed, non-widget span.
5646 function lineIsHidden(doc, line) {
5647 var sps = sawCollapsedSpans && line.markedSpans;
5648 if (sps) for (var sp, i = 0; i < sps.length; ++i) {
5649 sp = sps[i];
5650 if (!sp.marker.collapsed) continue;
5651 if (sp.from == null) return true;
5652 if (sp.marker.widgetNode) continue;
5653 if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
5654 return true;
5655 }
5656 }
5657 function lineIsHiddenInner(doc, line, span) {
5658 if (span.to == null) {
5659 var end = span.marker.find(1, true);
5660 return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
5661 }
5662 if (span.marker.inclusiveRight && span.to == line.text.length)
5663 return true;
5664 for (var sp, i = 0; i < line.markedSpans.length; ++i) {
5665 sp = line.markedSpans[i];
5666 if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
5667 (sp.to == null || sp.to != span.from) &&
5668 (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
5669 lineIsHiddenInner(doc, line, sp)) return true;
5670 }
5671 }
5672
5673 // LINE WIDGETS
5674
5675 // Line widgets are block elements displayed above or below a line.
5676
5677 var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
5678 if (options) for (var opt in options) if (options.hasOwnProperty(opt))
5679 this[opt] = options[opt];
5680 this.cm = cm;
5681 this.node = node;
5682 };
5683 eventMixin(LineWidget);
5684
5685 function adjustScrollWhenAboveVisible(cm, line, diff) {
5686 if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
5687 addToScrollPos(cm, null, diff);
5688 }
5689
5690 LineWidget.prototype.clear = function() {
5691 var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
5692 if (no == null || !ws) return;
5693 for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
5694 if (!ws.length) line.widgets = null;
5695 var height = widgetHeight(this);
5696 runInOp(cm, function() {
5697 adjustScrollWhenAboveVisible(cm, line, -height);
5698 regLineChange(cm, no, "widget");
5699 updateLineHeight(line, Math.max(0, line.height - height));
5700 });
5701 };
5702 LineWidget.prototype.changed = function() {
5703 var oldH = this.height, cm = this.cm, line = this.line;
5704 this.height = null;
5705 var diff = widgetHeight(this) - oldH;
5706 if (!diff) return;
5707 runInOp(cm, function() {
5708 cm.curOp.forceUpdate = true;
5709 adjustScrollWhenAboveVisible(cm, line, diff);
5710 updateLineHeight(line, line.height + diff);
5711 });
5712 };
5713
5714 function widgetHeight(widget) {
5715 if (widget.height != null) return widget.height;
5716 if (!contains(document.body, widget.node)) {
5717 var parentStyle = "position: relative;";
5718 if (widget.coverGutter)
5719 parentStyle += "margin-left: -" + widget.cm.getGutterElement().offsetWidth + "px;";
5720 removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle));
5721 }
5722 return widget.height = widget.node.offsetHeight;
5723 }
5724
5725 function addLineWidget(cm, handle, node, options) {
5726 var widget = new LineWidget(cm, node, options);
5727 if (widget.noHScroll) cm.display.alignWidgets = true;
5728 changeLine(cm.doc, handle, "widget", function(line) {
5729 var widgets = line.widgets || (line.widgets = []);
5730 if (widget.insertAt == null) widgets.push(widget);
5731 else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
5732 widget.line = line;
5733 if (!lineIsHidden(cm.doc, line)) {
5734 var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
5735 updateLineHeight(line, line.height + widgetHeight(widget));
5736 if (aboveVisible) addToScrollPos(cm, null, widget.height);
5737 cm.curOp.forceUpdate = true;
5738 }
5739 return true;
5740 });
5741 return widget;
5742 }
5743
5744 // LINE DATA STRUCTURE
5745
5746 // Line objects. These hold state related to a line, including
5747 // highlighting info (the styles array).
5748 var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
5749 this.text = text;
5750 attachMarkedSpans(this, markedSpans);
5751 this.height = estimateHeight ? estimateHeight(this) : 1;
5752 };
5753 eventMixin(Line);
5754 Line.prototype.lineNo = function() { return lineNo(this); };
5755
5756 // Change the content (text, markers) of a line. Automatically
5757 // invalidates cached information and tries to re-estimate the
5758 // line's height.
5759 function updateLine(line, text, markedSpans, estimateHeight) {
5760 line.text = text;
5761 if (line.stateAfter) line.stateAfter = null;
5762 if (line.styles) line.styles = null;
5763 if (line.order != null) line.order = null;
5764 detachMarkedSpans(line);
5765 attachMarkedSpans(line, markedSpans);
5766 var estHeight = estimateHeight ? estimateHeight(line) : 1;
5767 if (estHeight != line.height) updateLineHeight(line, estHeight);
5768 }
5769
5770 // Detach a line from the document tree and its markers.
5771 function cleanUpLine(line) {
5772 line.parent = null;
5773 detachMarkedSpans(line);
5774 }
5775
5776 function extractLineClasses(type, output) {
5777 if (type) for (;;) {
5778 var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
5779 if (!lineClass) break;
5780 type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
5781 var prop = lineClass[1] ? "bgClass" : "textClass";
5782 if (output[prop] == null)
5783 output[prop] = lineClass[2];
5784 else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
5785 output[prop] += " " + lineClass[2];
5786 }
5787 return type;
5788 }
5789
5790 function callBlankLine(mode, state) {
5791 if (mode.blankLine) return mode.blankLine(state);
5792 if (!mode.innerMode) return;
5793 var inner = CodeMirror.innerMode(mode, state);
5794 if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
5795 }
5796
5797 function readToken(mode, stream, state) {
5798 for (var i = 0; i < 10; i++) {
5799 var style = mode.token(stream, state);
5800 if (stream.pos > stream.start) return style;
5801 }
5802 throw new Error("Mode " + mode.name + " failed to advance stream.");
5803 }
5804
5805 // Run the given mode's parser over a line, calling f for each token.
5806 function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
5807 var flattenSpans = mode.flattenSpans;
5808 if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
5809 var curStart = 0, curStyle = null;
5810 var stream = new StringStream(text, cm.options.tabSize), style;
5811 if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
5812 while (!stream.eol()) {
5813 if (stream.pos > cm.options.maxHighlightLength) {
5814 flattenSpans = false;
5815 if (forceToEnd) processLine(cm, text, state, stream.pos);
5816 stream.pos = text.length;
5817 style = null;
5818 } else {
5819 style = extractLineClasses(readToken(mode, stream, state), lineClasses);
5820 }
5821 if (cm.options.addModeClass) {
5822 var mName = CodeMirror.innerMode(mode, state).mode.name;
5823 if (mName) style = "m-" + (style ? mName + " " + style : mName);
5824 }
5825 if (!flattenSpans || curStyle != style) {
5826 if (curStart < stream.start) f(stream.start, curStyle);
5827 curStart = stream.start; curStyle = style;
5828 }
5829 stream.start = stream.pos;
5830 }
5831 while (curStart < stream.pos) {
5832 // Webkit seems to refuse to render text nodes longer than 57444 characters
5833 var pos = Math.min(stream.pos, curStart + 50000);
5834 f(pos, curStyle);
5835 curStart = pos;
5836 }
5837 }
5838
5839 // Compute a style array (an array starting with a mode generation
5840 // -- for invalidation -- followed by pairs of end positions and
5841 // style strings), which is used to highlight the tokens on the
5842 // line.
5843 function highlightLine(cm, line, state, forceToEnd) {
5844 // A styles array always starts with a number identifying the
5845 // mode/overlays that it is based on (for easy invalidation).
5846 var st = [cm.state.modeGen], lineClasses = {};
5847 // Compute the base array of styles
5848 runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
5849 st.push(end, style);
5850 }, lineClasses, forceToEnd);
5851
5852 // Run overlays, adjust style array.
5853 for (var o = 0; o < cm.state.overlays.length; ++o) {
5854 var overlay = cm.state.overlays[o], i = 1, at = 0;
5855 runMode(cm, line.text, overlay.mode, true, function(end, style) {
5856 var start = i;
5857 // Ensure there's a token end at the current position, and that i points at it
5858 while (at < end) {
5859 var i_end = st[i];
5860 if (i_end > end)
5861 st.splice(i, 1, end, st[i+1], i_end);
5862 i += 2;
5863 at = Math.min(end, i_end);
5864 }
5865 if (!style) return;
5866 if (overlay.opaque) {
5867 st.splice(start, i - start, end, "cm-overlay " + style);
5868 i = start + 2;
5869 } else {
5870 for (; start < i; start += 2) {
5871 var cur = st[start+1];
5872 st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
5873 }
5874 }
5875 }, lineClasses);
5876 }
5877
5878 return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
5879 }
5880
5881 function getLineStyles(cm, line) {
5882 if (!line.styles || line.styles[0] != cm.state.modeGen) {
5883 var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
5884 line.styles = result.styles;
5885 if (result.classes) line.styleClasses = result.classes;
5886 else if (line.styleClasses) line.styleClasses = null;
5887 }
5888 return line.styles;
5889 }
5890
5891 // Lightweight form of highlight -- proceed over this line and
5892 // update state, but don't save a style array. Used for lines that
5893 // aren't currently visible.
5894 function processLine(cm, text, state, startAt) {
5895 var mode = cm.doc.mode;
5896 var stream = new StringStream(text, cm.options.tabSize);
5897 stream.start = stream.pos = startAt || 0;
5898 if (text == "") callBlankLine(mode, state);
5899 while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
5900 readToken(mode, stream, state);
5901 stream.start = stream.pos;
5902 }
5903 }
5904
5905 // Convert a style as returned by a mode (either null, or a string
5906 // containing one or more styles) to a CSS style. This is cached,
5907 // and also looks for line-wide styles.
5908 var styleToClassCache = {}, styleToClassCacheWithMode = {};
5909 function interpretTokenStyle(style, options) {
5910 if (!style || /^\s*$/.test(style)) return null;
5911 var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
5912 return cache[style] ||
5913 (cache[style] = style.replace(/\S+/g, "cm-$&"));
5914 }
5915
5916 // Render the DOM representation of the text of a line. Also builds
5917 // up a 'line map', which points at the DOM nodes that represent
5918 // specific stretches of text, and is used by the measuring code.
5919 // The returned object contains the DOM node, this map, and
5920 // information about line-wide styles that were set by the mode.
5921 function buildLineContent(cm, lineView) {
5922 // The padding-right forces the element to have a 'border', which
5923 // is needed on Webkit to be able to get line-level bounding
5924 // rectangles for it (in measureChar).
5925 var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
5926 var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
5927 lineView.measure = {};
5928
5929 // Iterate over the logical lines that make up this visual line.
5930 for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
5931 var line = i ? lineView.rest[i - 1] : lineView.line, order;
5932 builder.pos = 0;
5933 builder.addToken = buildToken;
5934 // Optionally wire in some hacks into the token-rendering
5935 // algorithm, to deal with browser quirks.
5936 if ((ie || webkit) && cm.getOption("lineWrapping"))
5937 builder.addToken = buildTokenSplitSpaces(builder.addToken);
5938 if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
5939 builder.addToken = buildTokenBadBidi(builder.addToken, order);
5940 builder.map = [];
5941 insertLineContent(line, builder, getLineStyles(cm, line));
5942 if (line.styleClasses) {
5943 if (line.styleClasses.bgClass)
5944 builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
5945 if (line.styleClasses.textClass)
5946 builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
5947 }
5948
5949 // Ensure at least a single node is present, for measuring.
5950 if (builder.map.length == 0)
5951 builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
5952
5953 // Store the map and a cache object for the current logical line
5954 if (i == 0) {
5955 lineView.measure.map = builder.map;
5956 lineView.measure.cache = {};
5957 } else {
5958 (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
5959 (lineView.measure.caches || (lineView.measure.caches = [])).push({});
5960 }
5961 }
5962
5963 signal(cm, "renderLine", cm, lineView.line, builder.pre);
5964 if (builder.pre.className)
5965 builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
5966 return builder;
5967 }
5968
5969 function defaultSpecialCharPlaceholder(ch) {
5970 var token = elt("span", "\u2022", "cm-invalidchar");
5971 token.title = "\\u" + ch.charCodeAt(0).toString(16);
5972 return token;
5973 }
5974
5975 // Build up the DOM representation for a single token, and add it to
5976 // the line map. Takes care to render special characters separately.
5977 function buildToken(builder, text, style, startStyle, endStyle, title) {
5978 if (!text) return;
5979 var special = builder.cm.options.specialChars, mustWrap = false;
5980 if (!special.test(text)) {
5981 builder.col += text.length;
5982 var content = document.createTextNode(text);
5983 builder.map.push(builder.pos, builder.pos + text.length, content);
5984 if (ie && ie_version < 9) mustWrap = true;
5985 builder.pos += text.length;
5986 } else {
5987 var content = document.createDocumentFragment(), pos = 0;
5988 while (true) {
5989 special.lastIndex = pos;
5990 var m = special.exec(text);
5991 var skipped = m ? m.index - pos : text.length - pos;
5992 if (skipped) {
5993 var txt = document.createTextNode(text.slice(pos, pos + skipped));
5994 if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
5995 else content.appendChild(txt);
5996 builder.map.push(builder.pos, builder.pos + skipped, txt);
5997 builder.col += skipped;
5998 builder.pos += skipped;
5999 }
6000 if (!m) break;
6001 pos += skipped + 1;
6002 if (m[0] == "\t") {
6003 var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
6004 var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
6005 builder.col += tabWidth;
6006 } else {
6007 var txt = builder.cm.options.specialCharPlaceholder(m[0]);
6008 if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
6009 else content.appendChild(txt);
6010 builder.col += 1;
6011 }
6012 builder.map.push(builder.pos, builder.pos + 1, txt);
6013 builder.pos++;
6014 }
6015 }
6016 if (style || startStyle || endStyle || mustWrap) {
6017 var fullStyle = style || "";
6018 if (startStyle) fullStyle += startStyle;
6019 if (endStyle) fullStyle += endStyle;
6020 var token = elt("span", [content], fullStyle);
6021 if (title) token.title = title;
6022 return builder.content.appendChild(token);
6023 }
6024 builder.content.appendChild(content);
6025 }
6026
6027 function buildTokenSplitSpaces(inner) {
6028 function split(old) {
6029 var out = " ";
6030 for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
6031 out += " ";
6032 return out;
6033 }
6034 return function(builder, text, style, startStyle, endStyle, title) {
6035 inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
6036 };
6037 }
6038
6039 // Work around nonsense dimensions being reported for stretches of
6040 // right-to-left text.
6041 function buildTokenBadBidi(inner, order) {
6042 return function(builder, text, style, startStyle, endStyle, title) {
6043 style = style ? style + " cm-force-border" : "cm-force-border";
6044 var start = builder.pos, end = start + text.length;
6045 for (;;) {
6046 // Find the part that overlaps with the start of this text
6047 for (var i = 0; i < order.length; i++) {
6048 var part = order[i];
6049 if (part.to > start && part.from <= start) break;
6050 }
6051 if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
6052 inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
6053 startStyle = null;
6054 text = text.slice(part.to - start);
6055 start = part.to;
6056 }
6057 };
6058 }
6059
6060 function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
6061 var widget = !ignoreWidget && marker.widgetNode;
6062 if (widget) {
6063 builder.map.push(builder.pos, builder.pos + size, widget);
6064 builder.content.appendChild(widget);
6065 }
6066 builder.pos += size;
6067 }
6068
6069 // Outputs a number of spans to make up a line, taking highlighting
6070 // and marked text into account.
6071 function insertLineContent(line, builder, styles) {
6072 var spans = line.markedSpans, allText = line.text, at = 0;
6073 if (!spans) {
6074 for (var i = 1; i < styles.length; i+=2)
6075 builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
6076 return;
6077 }
6078
6079 var len = allText.length, pos = 0, i = 1, text = "", style;
6080 var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
6081 for (;;) {
6082 if (nextChange == pos) { // Update current marker set
6083 spanStyle = spanEndStyle = spanStartStyle = title = "";
6084 collapsed = null; nextChange = Infinity;
6085 var foundBookmarks = [];
6086 for (var j = 0; j < spans.length; ++j) {
6087 var sp = spans[j], m = sp.marker;
6088 if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
6089 if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
6090 if (m.className) spanStyle += " " + m.className;
6091 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
6092 if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
6093 if (m.title && !title) title = m.title;
6094 if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
6095 collapsed = sp;
6096 } else if (sp.from > pos && nextChange > sp.from) {
6097 nextChange = sp.from;
6098 }
6099 if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
6100 }
6101 if (collapsed && (collapsed.from || 0) == pos) {
6102 buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
6103 collapsed.marker, collapsed.from == null);
6104 if (collapsed.to == null) return;
6105 }
6106 if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
6107 buildCollapsedSpan(builder, 0, foundBookmarks[j]);
6108 }
6109 if (pos >= len) break;
6110
6111 var upto = Math.min(len, nextChange);
6112 while (true) {
6113 if (text) {
6114 var end = pos + text.length;
6115 if (!collapsed) {
6116 var tokenText = end > upto ? text.slice(0, upto - pos) : text;
6117 builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
6118 spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
6119 }
6120 if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
6121 pos = end;
6122 spanStartStyle = "";
6123 }
6124 text = allText.slice(at, at = styles[i++]);
6125 style = interpretTokenStyle(styles[i++], builder.cm.options);
6126 }
6127 }
6128 }
6129
6130 // DOCUMENT DATA STRUCTURE
6131
6132 // By default, updates that start and end at the beginning of a line
6133 // are treated specially, in order to make the association of line
6134 // widgets and marker elements with the text behave more intuitive.
6135 function isWholeLineUpdate(doc, change) {
6136 return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
6137 (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
6138 }
6139
6140 // Perform a change on the document data structure.
6141 function updateDoc(doc, change, markedSpans, estimateHeight) {
6142 function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
6143 function update(line, text, spans) {
6144 updateLine(line, text, spans, estimateHeight);
6145 signalLater(line, "change", line, change);
6146 }
6147
6148 var from = change.from, to = change.to, text = change.text;
6149 var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
6150 var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
6151
6152 // Adjust the line structure
6153 if (isWholeLineUpdate(doc, change)) {
6154 // This is a whole-line replace. Treated specially to make
6155 // sure line objects move the way they are supposed to.
6156 for (var i = 0, added = []; i < text.length - 1; ++i)
6157 added.push(new Line(text[i], spansFor(i), estimateHeight));
6158 update(lastLine, lastLine.text, lastSpans);
6159 if (nlines) doc.remove(from.line, nlines);
6160 if (added.length) doc.insert(from.line, added);
6161 } else if (firstLine == lastLine) {
6162 if (text.length == 1) {
6163 update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
6164 } else {
6165 for (var added = [], i = 1; i < text.length - 1; ++i)
6166 added.push(new Line(text[i], spansFor(i), estimateHeight));
6167 added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
6168 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6169 doc.insert(from.line + 1, added);
6170 }
6171 } else if (text.length == 1) {
6172 update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
6173 doc.remove(from.line + 1, nlines);
6174 } else {
6175 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6176 update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
6177 for (var i = 1, added = []; i < text.length - 1; ++i)
6178 added.push(new Line(text[i], spansFor(i), estimateHeight));
6179 if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
6180 doc.insert(from.line + 1, added);
6181 }
6182
6183 signalLater(doc, "change", doc, change);
6184 }
6185
6186 // The document is represented as a BTree consisting of leaves, with
6187 // chunk of lines in them, and branches, with up to ten leaves or
6188 // other branch nodes below them. The top node is always a branch
6189 // node, and is the document object itself (meaning it has
6190 // additional methods and properties).
6191 //
6192 // All nodes have parent links. The tree is used both to go from
6193 // line numbers to line objects, and to go from objects to numbers.
6194 // It also indexes by height, and is used to convert between height
6195 // and line object, and to find the total height of the document.
6196 //
6197 // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
6198
6199 function LeafChunk(lines) {
6200 this.lines = lines;
6201 this.parent = null;
6202 for (var i = 0, height = 0; i < lines.length; ++i) {
6203 lines[i].parent = this;
6204 height += lines[i].height;
6205 }
6206 this.height = height;
6207 }
6208
6209 LeafChunk.prototype = {
6210 chunkSize: function() { return this.lines.length; },
6211 // Remove the n lines at offset 'at'.
6212 removeInner: function(at, n) {
6213 for (var i = at, e = at + n; i < e; ++i) {
6214 var line = this.lines[i];
6215 this.height -= line.height;
6216 cleanUpLine(line);
6217 signalLater(line, "delete");
6218 }
6219 this.lines.splice(at, n);
6220 },
6221 // Helper used to collapse a small branch into a single leaf.
6222 collapse: function(lines) {
6223 lines.push.apply(lines, this.lines);
6224 },
6225 // Insert the given array of lines at offset 'at', count them as
6226 // having the given height.
6227 insertInner: function(at, lines, height) {
6228 this.height += height;
6229 this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
6230 for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
6231 },
6232 // Used to iterate over a part of the tree.
6233 iterN: function(at, n, op) {
6234 for (var e = at + n; at < e; ++at)
6235 if (op(this.lines[at])) return true;
6236 }
6237 };
6238
6239 function BranchChunk(children) {
6240 this.children = children;
6241 var size = 0, height = 0;
6242 for (var i = 0; i < children.length; ++i) {
6243 var ch = children[i];
6244 size += ch.chunkSize(); height += ch.height;
6245 ch.parent = this;
6246 }
6247 this.size = size;
6248 this.height = height;
6249 this.parent = null;
6250 }
6251
6252 BranchChunk.prototype = {
6253 chunkSize: function() { return this.size; },
6254 removeInner: function(at, n) {
6255 this.size -= n;
6256 for (var i = 0; i < this.children.length; ++i) {
6257 var child = this.children[i], sz = child.chunkSize();
6258 if (at < sz) {
6259 var rm = Math.min(n, sz - at), oldHeight = child.height;
6260 child.removeInner(at, rm);
6261 this.height -= oldHeight - child.height;
6262 if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
6263 if ((n -= rm) == 0) break;
6264 at = 0;
6265 } else at -= sz;
6266 }
6267 // If the result is smaller than 25 lines, ensure that it is a
6268 // single leaf node.
6269 if (this.size - n < 25 &&
6270 (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
6271 var lines = [];
6272 this.collapse(lines);
6273 this.children = [new LeafChunk(lines)];
6274 this.children[0].parent = this;
6275 }
6276 },
6277 collapse: function(lines) {
6278 for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
6279 },
6280 insertInner: function(at, lines, height) {
6281 this.size += lines.length;
6282 this.height += height;
6283 for (var i = 0; i < this.children.length; ++i) {
6284 var child = this.children[i], sz = child.chunkSize();
6285 if (at <= sz) {
6286 child.insertInner(at, lines, height);
6287 if (child.lines && child.lines.length > 50) {
6288 while (child.lines.length > 50) {
6289 var spilled = child.lines.splice(child.lines.length - 25, 25);
6290 var newleaf = new LeafChunk(spilled);
6291 child.height -= newleaf.height;
6292 this.children.splice(i + 1, 0, newleaf);
6293 newleaf.parent = this;
6294 }
6295 this.maybeSpill();
6296 }
6297 break;
6298 }
6299 at -= sz;
6300 }
6301 },
6302 // When a node has grown, check whether it should be split.
6303 maybeSpill: function() {
6304 if (this.children.length <= 10) return;
6305 var me = this;
6306 do {
6307 var spilled = me.children.splice(me.children.length - 5, 5);
6308 var sibling = new BranchChunk(spilled);
6309 if (!me.parent) { // Become the parent node
6310 var copy = new BranchChunk(me.children);
6311 copy.parent = me;
6312 me.children = [copy, sibling];
6313 me = copy;
6314 } else {
6315 me.size -= sibling.size;
6316 me.height -= sibling.height;
6317 var myIndex = indexOf(me.parent.children, me);
6318 me.parent.children.splice(myIndex + 1, 0, sibling);
6319 }
6320 sibling.parent = me.parent;
6321 } while (me.children.length > 10);
6322 me.parent.maybeSpill();
6323 },
6324 iterN: function(at, n, op) {
6325 for (var i = 0; i < this.children.length; ++i) {
6326 var child = this.children[i], sz = child.chunkSize();
6327 if (at < sz) {
6328 var used = Math.min(n, sz - at);
6329 if (child.iterN(at, used, op)) return true;
6330 if ((n -= used) == 0) break;
6331 at = 0;
6332 } else at -= sz;
6333 }
6334 }
6335 };
6336
6337 var nextDocId = 0;
6338 var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
6339 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
6340 if (firstLine == null) firstLine = 0;
6341
6342 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
6343 this.first = firstLine;
6344 this.scrollTop = this.scrollLeft = 0;
6345 this.cantEdit = false;
6346 this.cleanGeneration = 1;
6347 this.frontier = firstLine;
6348 var start = Pos(firstLine, 0);
6349 this.sel = simpleSelection(start);
6350 this.history = new History(null);
6351 this.id = ++nextDocId;
6352 this.modeOption = mode;
6353
6354 if (typeof text == "string") text = splitLines(text);
6355 updateDoc(this, {from: start, to: start, text: text});
6356 setSelection(this, simpleSelection(start), sel_dontScroll);
6357 };
6358
6359 Doc.prototype = createObj(BranchChunk.prototype, {
6360 constructor: Doc,
6361 // Iterate over the document. Supports two forms -- with only one
6362 // argument, it calls that for each line in the document. With
6363 // three, it iterates over the range given by the first two (with
6364 // the second being non-inclusive).
6365 iter: function(from, to, op) {
6366 if (op) this.iterN(from - this.first, to - from, op);
6367 else this.iterN(this.first, this.first + this.size, from);
6368 },
6369
6370 // Non-public interface for adding and removing lines.
6371 insert: function(at, lines) {
6372 var height = 0;
6373 for (var i = 0; i < lines.length; ++i) height += lines[i].height;
6374 this.insertInner(at - this.first, lines, height);
6375 },
6376 remove: function(at, n) { this.removeInner(at - this.first, n); },
6377
6378 // From here, the methods are part of the public interface. Most
6379 // are also available from CodeMirror (editor) instances.
6380
6381 getValue: function(lineSep) {
6382 var lines = getLines(this, this.first, this.first + this.size);
6383 if (lineSep === false) return lines;
6384 return lines.join(lineSep || "\n");
6385 },
6386 setValue: docMethodOp(function(code) {
6387 var top = Pos(this.first, 0), last = this.first + this.size - 1;
6388 makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
6389 text: splitLines(code), origin: "setValue"}, true);
6390 setSelection(this, simpleSelection(top));
6391 }),
6392 replaceRange: function(code, from, to, origin) {
6393 from = clipPos(this, from);
6394 to = to ? clipPos(this, to) : from;
6395 replaceRange(this, code, from, to, origin);
6396 },
6397 getRange: function(from, to, lineSep) {
6398 var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
6399 if (lineSep === false) return lines;
6400 return lines.join(lineSep || "\n");
6401 },
6402
6403 getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
6404
6405 getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
6406 getLineNumber: function(line) {return lineNo(line);},
6407
6408 getLineHandleVisualStart: function(line) {
6409 if (typeof line == "number") line = getLine(this, line);
6410 return visualLine(line);
6411 },
6412
6413 lineCount: function() {return this.size;},
6414 firstLine: function() {return this.first;},
6415 lastLine: function() {return this.first + this.size - 1;},
6416
6417 clipPos: function(pos) {return clipPos(this, pos);},
6418
6419 getCursor: function(start) {
6420 var range = this.sel.primary(), pos;
6421 if (start == null || start == "head") pos = range.head;
6422 else if (start == "anchor") pos = range.anchor;
6423 else if (start == "end" || start == "to" || start === false) pos = range.to();
6424 else pos = range.from();
6425 return pos;
6426 },
6427 listSelections: function() { return this.sel.ranges; },
6428 somethingSelected: function() {return this.sel.somethingSelected();},
6429
6430 setCursor: docMethodOp(function(line, ch, options) {
6431 setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
6432 }),
6433 setSelection: docMethodOp(function(anchor, head, options) {
6434 setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
6435 }),
6436 extendSelection: docMethodOp(function(head, other, options) {
6437 extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
6438 }),
6439 extendSelections: docMethodOp(function(heads, options) {
6440 extendSelections(this, clipPosArray(this, heads, options));
6441 }),
6442 extendSelectionsBy: docMethodOp(function(f, options) {
6443 extendSelections(this, map(this.sel.ranges, f), options);
6444 }),
6445 setSelections: docMethodOp(function(ranges, primary, options) {
6446 if (!ranges.length) return;
6447 for (var i = 0, out = []; i < ranges.length; i++)
6448 out[i] = new Range(clipPos(this, ranges[i].anchor),
6449 clipPos(this, ranges[i].head));
6450 if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
6451 setSelection(this, normalizeSelection(out, primary), options);
6452 }),
6453 addSelection: docMethodOp(function(anchor, head, options) {
6454 var ranges = this.sel.ranges.slice(0);
6455 ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
6456 setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
6457 }),
6458
6459 getSelection: function(lineSep) {
6460 var ranges = this.sel.ranges, lines;
6461 for (var i = 0; i < ranges.length; i++) {
6462 var sel = getBetween(this, ranges[i].from(), ranges[i].to());
6463 lines = lines ? lines.concat(sel) : sel;
6464 }
6465 if (lineSep === false) return lines;
6466 else return lines.join(lineSep || "\n");
6467 },
6468 getSelections: function(lineSep) {
6469 var parts = [], ranges = this.sel.ranges;
6470 for (var i = 0; i < ranges.length; i++) {
6471 var sel = getBetween(this, ranges[i].from(), ranges[i].to());
6472 if (lineSep !== false) sel = sel.join(lineSep || "\n");
6473 parts[i] = sel;
6474 }
6475 return parts;
6476 },
6477 replaceSelection: function(code, collapse, origin) {
6478 var dup = [];
6479 for (var i = 0; i < this.sel.ranges.length; i++)
6480 dup[i] = code;
6481 this.replaceSelections(dup, collapse, origin || "+input");
6482 },
6483 replaceSelections: docMethodOp(function(code, collapse, origin) {
6484 var changes = [], sel = this.sel;
6485 for (var i = 0; i < sel.ranges.length; i++) {
6486 var range = sel.ranges[i];
6487 changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
6488 }
6489 var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
6490 for (var i = changes.length - 1; i >= 0; i--)
6491 makeChange(this, changes[i]);
6492 if (newSel) setSelectionReplaceHistory(this, newSel);
6493 else if (this.cm) ensureCursorVisible(this.cm);
6494 }),
6495 undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
6496 redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
6497 undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
6498 redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
6499
6500 setExtending: function(val) {this.extend = val;},
6501 getExtending: function() {return this.extend;},
6502
6503 historySize: function() {
6504 var hist = this.history, done = 0, undone = 0;
6505 for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
6506 for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
6507 return {undo: done, redo: undone};
6508 },
6509 clearHistory: function() {this.history = new History(this.history.maxGeneration);},
6510
6511 markClean: function() {
6512 this.cleanGeneration = this.changeGeneration(true);
6513 },
6514 changeGeneration: function(forceSplit) {
6515 if (forceSplit)
6516 this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
6517 return this.history.generation;
6518 },
6519 isClean: function (gen) {
6520 return this.history.generation == (gen || this.cleanGeneration);
6521 },
6522
6523 getHistory: function() {
6524 return {done: copyHistoryArray(this.history.done),
6525 undone: copyHistoryArray(this.history.undone)};
6526 },
6527 setHistory: function(histData) {
6528 var hist = this.history = new History(this.history.maxGeneration);
6529 hist.done = copyHistoryArray(histData.done.slice(0), null, true);
6530 hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
6531 },
6532
6533 addLineClass: docMethodOp(function(handle, where, cls) {
6534 return changeLine(this, handle, "class", function(line) {
6535 var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
6536 if (!line[prop]) line[prop] = cls;
6537 else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
6538 else line[prop] += " " + cls;
6539 return true;
6540 });
6541 }),
6542 removeLineClass: docMethodOp(function(handle, where, cls) {
6543 return changeLine(this, handle, "class", function(line) {
6544 var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
6545 var cur = line[prop];
6546 if (!cur) return false;
6547 else if (cls == null) line[prop] = null;
6548 else {
6549 var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
6550 if (!found) return false;
6551 var end = found.index + found[0].length;
6552 line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
6553 }
6554 return true;
6555 });
6556 }),
6557
6558 markText: function(from, to, options) {
6559 return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
6560 },
6561 setBookmark: function(pos, options) {
6562 var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
6563 insertLeft: options && options.insertLeft,
6564 clearWhenEmpty: false, shared: options && options.shared};
6565 pos = clipPos(this, pos);
6566 return markText(this, pos, pos, realOpts, "bookmark");
6567 },
6568 findMarksAt: function(pos) {
6569 pos = clipPos(this, pos);
6570 var markers = [], spans = getLine(this, pos.line).markedSpans;
6571 if (spans) for (var i = 0; i < spans.length; ++i) {
6572 var span = spans[i];
6573 if ((span.from == null || span.from <= pos.ch) &&
6574 (span.to == null || span.to >= pos.ch))
6575 markers.push(span.marker.parent || span.marker);
6576 }
6577 return markers;
6578 },
6579 findMarks: function(from, to, filter) {
6580 from = clipPos(this, from); to = clipPos(this, to);
6581 var found = [], lineNo = from.line;
6582 this.iter(from.line, to.line + 1, function(line) {
6583 var spans = line.markedSpans;
6584 if (spans) for (var i = 0; i < spans.length; i++) {
6585 var span = spans[i];
6586 if (!(lineNo == from.line && from.ch > span.to ||
6587 span.from == null && lineNo != from.line||
6588 lineNo == to.line && span.from > to.ch) &&
6589 (!filter || filter(span.marker)))
6590 found.push(span.marker.parent || span.marker);
6591 }
6592 ++lineNo;
6593 });
6594 return found;
6595 },
6596 getAllMarks: function() {
6597 var markers = [];
6598 this.iter(function(line) {
6599 var sps = line.markedSpans;
6600 if (sps) for (var i = 0; i < sps.length; ++i)
6601 if (sps[i].from != null) markers.push(sps[i].marker);
6602 });
6603 return markers;
6604 },
6605
6606 posFromIndex: function(off) {
6607 var ch, lineNo = this.first;
6608 this.iter(function(line) {
6609 var sz = line.text.length + 1;
6610 if (sz > off) { ch = off; return true; }
6611 off -= sz;
6612 ++lineNo;
6613 });
6614 return clipPos(this, Pos(lineNo, ch));
6615 },
6616 indexFromPos: function (coords) {
6617 coords = clipPos(this, coords);
6618 var index = coords.ch;
6619 if (coords.line < this.first || coords.ch < 0) return 0;
6620 this.iter(this.first, coords.line, function (line) {
6621 index += line.text.length + 1;
6622 });
6623 return index;
6624 },
6625
6626 copy: function(copyHistory) {
6627 var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
6628 doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
6629 doc.sel = this.sel;
6630 doc.extend = false;
6631 if (copyHistory) {
6632 doc.history.undoDepth = this.history.undoDepth;
6633 doc.setHistory(this.getHistory());
6634 }
6635 return doc;
6636 },
6637
6638 linkedDoc: function(options) {
6639 if (!options) options = {};
6640 var from = this.first, to = this.first + this.size;
6641 if (options.from != null && options.from > from) from = options.from;
6642 if (options.to != null && options.to < to) to = options.to;
6643 var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
6644 if (options.sharedHist) copy.history = this.history;
6645 (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
6646 copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
6647 copySharedMarkers(copy, findSharedMarkers(this));
6648 return copy;
6649 },
6650 unlinkDoc: function(other) {
6651 if (other instanceof CodeMirror) other = other.doc;
6652 if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
6653 var link = this.linked[i];
6654 if (link.doc != other) continue;
6655 this.linked.splice(i, 1);
6656 other.unlinkDoc(this);
6657 detachSharedMarkers(findSharedMarkers(this));
6658 break;
6659 }
6660 // If the histories were shared, split them again
6661 if (other.history == this.history) {
6662 var splitIds = [other.id];
6663 linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
6664 other.history = new History(null);
6665 other.history.done = copyHistoryArray(this.history.done, splitIds);
6666 other.history.undone = copyHistoryArray(this.history.undone, splitIds);
6667 }
6668 },
6669 iterLinkedDocs: function(f) {linkedDocs(this, f);},
6670
6671 getMode: function() {return this.mode;},
6672 getEditor: function() {return this.cm;}
6673 });
6674
6675 // Public alias.
6676 Doc.prototype.eachLine = Doc.prototype.iter;
6677
6678 // Set up methods on CodeMirror's prototype to redirect to the editor's document.
6679 var dontDelegate = "iter insert remove copy getEditor".split(" ");
6680 for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
6681 CodeMirror.prototype[prop] = (function(method) {
6682 return function() {return method.apply(this.doc, arguments);};
6683 })(Doc.prototype[prop]);
6684
6685 eventMixin(Doc);
6686
6687 // Call f for all linked documents.
6688 function linkedDocs(doc, f, sharedHistOnly) {
6689 function propagate(doc, skip, sharedHist) {
6690 if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
6691 var rel = doc.linked[i];
6692 if (rel.doc == skip) continue;
6693 var shared = sharedHist && rel.sharedHist;
6694 if (sharedHistOnly && !shared) continue;
6695 f(rel.doc, shared);
6696 propagate(rel.doc, doc, shared);
6697 }
6698 }
6699 propagate(doc, null, true);
6700 }
6701
6702 // Attach a document to an editor.
6703 function attachDoc(cm, doc) {
6704 if (doc.cm) throw new Error("This document is already in use.");
6705 cm.doc = doc;
6706 doc.cm = cm;
6707 estimateLineHeights(cm);
6708 loadMode(cm);
6709 if (!cm.options.lineWrapping) findMaxLine(cm);
6710 cm.options.mode = doc.modeOption;
6711 regChange(cm);
6712 }
6713
6714 // LINE UTILITIES
6715
6716 // Find the line object corresponding to the given line number.
6717 function getLine(doc, n) {
6718 n -= doc.first;
6719 if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
6720 for (var chunk = doc; !chunk.lines;) {
6721 for (var i = 0;; ++i) {
6722 var child = chunk.children[i], sz = child.chunkSize();
6723 if (n < sz) { chunk = child; break; }
6724 n -= sz;
6725 }
6726 }
6727 return chunk.lines[n];
6728 }
6729
6730 // Get the part of a document between two positions, as an array of
6731 // strings.
6732 function getBetween(doc, start, end) {
6733 var out = [], n = start.line;
6734 doc.iter(start.line, end.line + 1, function(line) {
6735 var text = line.text;
6736 if (n == end.line) text = text.slice(0, end.ch);
6737 if (n == start.line) text = text.slice(start.ch);
6738 out.push(text);
6739 ++n;
6740 });
6741 return out;
6742 }
6743 // Get the lines between from and to, as array of strings.
6744 function getLines(doc, from, to) {
6745 var out = [];
6746 doc.iter(from, to, function(line) { out.push(line.text); });
6747 return out;
6748 }
6749
6750 // Update the height of a line, propagating the height change
6751 // upwards to parent nodes.
6752 function updateLineHeight(line, height) {
6753 var diff = height - line.height;
6754 if (diff) for (var n = line; n; n = n.parent) n.height += diff;
6755 }
6756
6757 // Given a line object, find its line number by walking up through
6758 // its parent links.
6759 function lineNo(line) {
6760 if (line.parent == null) return null;
6761 var cur = line.parent, no = indexOf(cur.lines, line);
6762 for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
6763 for (var i = 0;; ++i) {
6764 if (chunk.children[i] == cur) break;
6765 no += chunk.children[i].chunkSize();
6766 }
6767 }
6768 return no + cur.first;
6769 }
6770
6771 // Find the line at the given vertical position, using the height
6772 // information in the document tree.
6773 function lineAtHeight(chunk, h) {
6774 var n = chunk.first;
6775 outer: do {
6776 for (var i = 0; i < chunk.children.length; ++i) {
6777 var child = chunk.children[i], ch = child.height;
6778 if (h < ch) { chunk = child; continue outer; }
6779 h -= ch;
6780 n += child.chunkSize();
6781 }
6782 return n;
6783 } while (!chunk.lines);
6784 for (var i = 0; i < chunk.lines.length; ++i) {
6785 var line = chunk.lines[i], lh = line.height;
6786 if (h < lh) break;
6787 h -= lh;
6788 }
6789 return n + i;
6790 }
6791
6792
6793 // Find the height above the given line.
6794 function heightAtLine(lineObj) {
6795 lineObj = visualLine(lineObj);
6796
6797 var h = 0, chunk = lineObj.parent;
6798 for (var i = 0; i < chunk.lines.length; ++i) {
6799 var line = chunk.lines[i];
6800 if (line == lineObj) break;
6801 else h += line.height;
6802 }
6803 for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
6804 for (var i = 0; i < p.children.length; ++i) {
6805 var cur = p.children[i];
6806 if (cur == chunk) break;
6807 else h += cur.height;
6808 }
6809 }
6810 return h;
6811 }
6812
6813 // Get the bidi ordering for the given line (and cache it). Returns
6814 // false for lines that are fully left-to-right, and an array of
6815 // BidiSpan objects otherwise.
6816 function getOrder(line) {
6817 var order = line.order;
6818 if (order == null) order = line.order = bidiOrdering(line.text);
6819 return order;
6820 }
6821
6822 // HISTORY
6823
6824 function History(startGen) {
6825 // Arrays of change events and selections. Doing something adds an
6826 // event to done and clears undo. Undoing moves events from done
6827 // to undone, redoing moves them in the other direction.
6828 this.done = []; this.undone = [];
6829 this.undoDepth = Infinity;
6830 // Used to track when changes can be merged into a single undo
6831 // event
6832 this.lastModTime = this.lastSelTime = 0;
6833 this.lastOp = this.lastSelOp = null;
6834 this.lastOrigin = this.lastSelOrigin = null;
6835 // Used by the isClean() method
6836 this.generation = this.maxGeneration = startGen || 1;
6837 }
6838
6839 // Create a history change event from an updateDoc-style change
6840 // object.
6841 function historyChangeFromChange(doc, change) {
6842 var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
6843 attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
6844 linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
6845 return histChange;
6846 }
6847
6848 // Pop all selection events off the end of a history array. Stop at
6849 // a change event.
6850 function clearSelectionEvents(array) {
6851 while (array.length) {
6852 var last = lst(array);
6853 if (last.ranges) array.pop();
6854 else break;
6855 }
6856 }
6857
6858 // Find the top change event in the history. Pop off selection
6859 // events that are in the way.
6860 function lastChangeEvent(hist, force) {
6861 if (force) {
6862 clearSelectionEvents(hist.done);
6863 return lst(hist.done);
6864 } else if (hist.done.length && !lst(hist.done).ranges) {
6865 return lst(hist.done);
6866 } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
6867 hist.done.pop();
6868 return lst(hist.done);
6869 }
6870 }
6871
6872 // Register a change in the history. Merges changes that are within
6873 // a single operation, ore are close together with an origin that
6874 // allows merging (starting with "+") into a single event.
6875 function addChangeToHistory(doc, change, selAfter, opId) {
6876 var hist = doc.history;
6877 hist.undone.length = 0;
6878 var time = +new Date, cur;
6879
6880 if ((hist.lastOp == opId ||
6881 hist.lastOrigin == change.origin && change.origin &&
6882 ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
6883 change.origin.charAt(0) == "*")) &&
6884 (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
6885 // Merge this change into the last event
6886 var last = lst(cur.changes);
6887 if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
6888 // Optimized case for simple insertion -- don't want to add
6889 // new changesets for every character typed
6890 last.to = changeEnd(change);
6891 } else {
6892 // Add new sub-event
6893 cur.changes.push(historyChangeFromChange(doc, change));
6894 }
6895 } else {
6896 // Can not be merged, start a new event.
6897 var before = lst(hist.done);
6898 if (!before || !before.ranges)
6899 pushSelectionToHistory(doc.sel, hist.done);
6900 cur = {changes: [historyChangeFromChange(doc, change)],
6901 generation: hist.generation};
6902 hist.done.push(cur);
6903 while (hist.done.length > hist.undoDepth) {
6904 hist.done.shift();
6905 if (!hist.done[0].ranges) hist.done.shift();
6906 }
6907 }
6908 hist.done.push(selAfter);
6909 hist.generation = ++hist.maxGeneration;
6910 hist.lastModTime = hist.lastSelTime = time;
6911 hist.lastOp = hist.lastSelOp = opId;
6912 hist.lastOrigin = hist.lastSelOrigin = change.origin;
6913
6914 if (!last) signal(doc, "historyAdded");
6915 }
6916
6917 function selectionEventCanBeMerged(doc, origin, prev, sel) {
6918 var ch = origin.charAt(0);
6919 return ch == "*" ||
6920 ch == "+" &&
6921 prev.ranges.length == sel.ranges.length &&
6922 prev.somethingSelected() == sel.somethingSelected() &&
6923 new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
6924 }
6925
6926 // Called whenever the selection changes, sets the new selection as
6927 // the pending selection in the history, and pushes the old pending
6928 // selection into the 'done' array when it was significantly
6929 // different (in number of selected ranges, emptiness, or time).
6930 function addSelectionToHistory(doc, sel, opId, options) {
6931 var hist = doc.history, origin = options && options.origin;
6932
6933 // A new event is started when the previous origin does not match
6934 // the current, or the origins don't allow matching. Origins
6935 // starting with * are always merged, those starting with + are
6936 // merged when similar and close together in time.
6937 if (opId == hist.lastSelOp ||
6938 (origin && hist.lastSelOrigin == origin &&
6939 (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
6940 selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
6941 hist.done[hist.done.length - 1] = sel;
6942 else
6943 pushSelectionToHistory(sel, hist.done);
6944
6945 hist.lastSelTime = +new Date;
6946 hist.lastSelOrigin = origin;
6947 hist.lastSelOp = opId;
6948 if (options && options.clearRedo !== false)
6949 clearSelectionEvents(hist.undone);
6950 }
6951
6952 function pushSelectionToHistory(sel, dest) {
6953 var top = lst(dest);
6954 if (!(top && top.ranges && top.equals(sel)))
6955 dest.push(sel);
6956 }
6957
6958 // Used to store marked span information in the history.
6959 function attachLocalSpans(doc, change, from, to) {
6960 var existing = change["spans_" + doc.id], n = 0;
6961 doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
6962 if (line.markedSpans)
6963 (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
6964 ++n;
6965 });
6966 }
6967
6968 // When un/re-doing restores text containing marked spans, those
6969 // that have been explicitly cleared should not be restored.
6970 function removeClearedSpans(spans) {
6971 if (!spans) return null;
6972 for (var i = 0, out; i < spans.length; ++i) {
6973 if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
6974 else if (out) out.push(spans[i]);
6975 }
6976 return !out ? spans : out.length ? out : null;
6977 }
6978
6979 // Retrieve and filter the old marked spans stored in a change event.
6980 function getOldSpans(doc, change) {
6981 var found = change["spans_" + doc.id];
6982 if (!found) return null;
6983 for (var i = 0, nw = []; i < change.text.length; ++i)
6984 nw.push(removeClearedSpans(found[i]));
6985 return nw;
6986 }
6987
6988 // Used both to provide a JSON-safe object in .getHistory, and, when
6989 // detaching a document, to split the history in two
6990 function copyHistoryArray(events, newGroup, instantiateSel) {
6991 for (var i = 0, copy = []; i < events.length; ++i) {
6992 var event = events[i];
6993 if (event.ranges) {
6994 copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
6995 continue;
6996 }
6997 var changes = event.changes, newChanges = [];
6998 copy.push({changes: newChanges});
6999 for (var j = 0; j < changes.length; ++j) {
7000 var change = changes[j], m;
7001 newChanges.push({from: change.from, to: change.to, text: change.text});
7002 if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
7003 if (indexOf(newGroup, Number(m[1])) > -1) {
7004 lst(newChanges)[prop] = change[prop];
7005 delete change[prop];
7006 }
7007 }
7008 }
7009 }
7010 return copy;
7011 }
7012
7013 // Rebasing/resetting history to deal with externally-sourced changes
7014
7015 function rebaseHistSelSingle(pos, from, to, diff) {
7016 if (to < pos.line) {
7017 pos.line += diff;
7018 } else if (from < pos.line) {
7019 pos.line = from;
7020 pos.ch = 0;
7021 }
7022 }
7023
7024 // Tries to rebase an array of history events given a change in the
7025 // document. If the change touches the same lines as the event, the
7026 // event, and everything 'behind' it, is discarded. If the change is
7027 // before the event, the event's positions are updated. Uses a
7028 // copy-on-write scheme for the positions, to avoid having to
7029 // reallocate them all on every rebase, but also avoid problems with
7030 // shared position objects being unsafely updated.
7031 function rebaseHistArray(array, from, to, diff) {
7032 for (var i = 0; i < array.length; ++i) {
7033 var sub = array[i], ok = true;
7034 if (sub.ranges) {
7035 if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
7036 for (var j = 0; j < sub.ranges.length; j++) {
7037 rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
7038 rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
7039 }
7040 continue;
7041 }
7042 for (var j = 0; j < sub.changes.length; ++j) {
7043 var cur = sub.changes[j];
7044 if (to < cur.from.line) {
7045 cur.from = Pos(cur.from.line + diff, cur.from.ch);
7046 cur.to = Pos(cur.to.line + diff, cur.to.ch);
7047 } else if (from <= cur.to.line) {
7048 ok = false;
7049 break;
7050 }
7051 }
7052 if (!ok) {
7053 array.splice(0, i + 1);
7054 i = 0;
7055 }
7056 }
7057 }
7058
7059 function rebaseHist(hist, change) {
7060 var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
7061 rebaseHistArray(hist.done, from, to, diff);
7062 rebaseHistArray(hist.undone, from, to, diff);
7063 }
7064
7065 // EVENT UTILITIES
7066
7067 // Due to the fact that we still support jurassic IE versions, some
7068 // compatibility wrappers are needed.
7069
7070 var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
7071 if (e.preventDefault) e.preventDefault();
7072 else e.returnValue = false;
7073 };
7074 var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
7075 if (e.stopPropagation) e.stopPropagation();
7076 else e.cancelBubble = true;
7077 };
7078 function e_defaultPrevented(e) {
7079 return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
7080 }
7081 var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
7082
7083 function e_target(e) {return e.target || e.srcElement;}
7084 function e_button(e) {
7085 var b = e.which;
7086 if (b == null) {
7087 if (e.button & 1) b = 1;
7088 else if (e.button & 2) b = 3;
7089 else if (e.button & 4) b = 2;
7090 }
7091 if (mac && e.ctrlKey && b == 1) b = 3;
7092 return b;
7093 }
7094
7095 // EVENT HANDLING
7096
7097 // Lightweight event framework. on/off also work on DOM nodes,
7098 // registering native DOM handlers.
7099
7100 var on = CodeMirror.on = function(emitter, type, f) {
7101 if (emitter.addEventListener)
7102 emitter.addEventListener(type, f, false);
7103 else if (emitter.attachEvent)
7104 emitter.attachEvent("on" + type, f);
7105 else {
7106 var map = emitter._handlers || (emitter._handlers = {});
7107 var arr = map[type] || (map[type] = []);
7108 arr.push(f);
7109 }
7110 };
7111
7112 var off = CodeMirror.off = function(emitter, type, f) {
7113 if (emitter.removeEventListener)
7114 emitter.removeEventListener(type, f, false);
7115 else if (emitter.detachEvent)
7116 emitter.detachEvent("on" + type, f);
7117 else {
7118 var arr = emitter._handlers && emitter._handlers[type];
7119 if (!arr) return;
7120 for (var i = 0; i < arr.length; ++i)
7121 if (arr[i] == f) { arr.splice(i, 1); break; }
7122 }
7123 };
7124
7125 var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
7126 var arr = emitter._handlers && emitter._handlers[type];
7127 if (!arr) return;
7128 var args = Array.prototype.slice.call(arguments, 2);
7129 for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
7130 };
7131
7132 var orphanDelayedCallbacks = null;
7133
7134 // Often, we want to signal events at a point where we are in the
7135 // middle of some work, but don't want the handler to start calling
7136 // other methods on the editor, which might be in an inconsistent
7137 // state or simply not expect any other events to happen.
7138 // signalLater looks whether there are any handlers, and schedules
7139 // them to be executed when the last operation ends, or, if no
7140 // operation is active, when a timeout fires.
7141 function signalLater(emitter, type /*, values...*/) {
7142 var arr = emitter._handlers && emitter._handlers[type];
7143 if (!arr) return;
7144 var args = Array.prototype.slice.call(arguments, 2), list;
7145 if (operationGroup) {
7146 list = operationGroup.delayedCallbacks;
7147 } else if (orphanDelayedCallbacks) {
7148 list = orphanDelayedCallbacks;
7149 } else {
7150 list = orphanDelayedCallbacks = [];
7151 setTimeout(fireOrphanDelayed, 0);
7152 }
7153 function bnd(f) {return function(){f.apply(null, args);};};
7154 for (var i = 0; i < arr.length; ++i)
7155 list.push(bnd(arr[i]));
7156 }
7157
7158 function fireOrphanDelayed() {
7159 var delayed = orphanDelayedCallbacks;
7160 orphanDelayedCallbacks = null;
7161 for (var i = 0; i < delayed.length; ++i) delayed[i]();
7162 }
7163
7164 // The DOM events that CodeMirror handles can be overridden by
7165 // registering a (non-DOM) handler on the editor for the event name,
7166 // and preventDefault-ing the event in that handler.
7167 function signalDOMEvent(cm, e, override) {
7168 signal(cm, override || e.type, cm, e);
7169 return e_defaultPrevented(e) || e.codemirrorIgnore;
7170 }
7171
7172 function signalCursorActivity(cm) {
7173 var arr = cm._handlers && cm._handlers.cursorActivity;
7174 if (!arr) return;
7175 var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
7176 for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
7177 set.push(arr[i]);
7178 }
7179
7180 function hasHandler(emitter, type) {
7181 var arr = emitter._handlers && emitter._handlers[type];
7182 return arr && arr.length > 0;
7183 }
7184
7185 // Add on and off methods to a constructor's prototype, to make
7186 // registering events on such objects more convenient.
7187 function eventMixin(ctor) {
7188 ctor.prototype.on = function(type, f) {on(this, type, f);};
7189 ctor.prototype.off = function(type, f) {off(this, type, f);};
7190 }
7191
7192 // MISC UTILITIES
7193
7194 // Number of pixels added to scroller and sizer to hide scrollbar
7195 var scrollerCutOff = 30;
7196
7197 // Returned or thrown by various protocols to signal 'I'm not
7198 // handling this'.
7199 var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
7200
7201 // Reused option objects for setSelection & friends
7202 var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
7203
7204 function Delayed() {this.id = null;}
7205 Delayed.prototype.set = function(ms, f) {
7206 clearTimeout(this.id);
7207 this.id = setTimeout(f, ms);
7208 };
7209
7210 // Counts the column offset in a string, taking tabs into account.
7211 // Used mostly to find indentation.
7212 var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
7213 if (end == null) {
7214 end = string.search(/[^\s\u00a0]/);
7215 if (end == -1) end = string.length;
7216 }
7217 for (var i = startIndex || 0, n = startValue || 0;;) {
7218 var nextTab = string.indexOf("\t", i);
7219 if (nextTab < 0 || nextTab >= end)
7220 return n + (end - i);
7221 n += nextTab - i;
7222 n += tabSize - (n % tabSize);
7223 i = nextTab + 1;
7224 }
7225 };
7226
7227 // The inverse of countColumn -- find the offset that corresponds to
7228 // a particular column.
7229 function findColumn(string, goal, tabSize) {
7230 for (var pos = 0, col = 0;;) {
7231 var nextTab = string.indexOf("\t", pos);
7232 if (nextTab == -1) nextTab = string.length;
7233 var skipped = nextTab - pos;
7234 if (nextTab == string.length || col + skipped >= goal)
7235 return pos + Math.min(skipped, goal - col);
7236 col += nextTab - pos;
7237 col += tabSize - (col % tabSize);
7238 pos = nextTab + 1;
7239 if (col >= goal) return pos;
7240 }
7241 }
7242
7243 var spaceStrs = [""];
7244 function spaceStr(n) {
7245 while (spaceStrs.length <= n)
7246 spaceStrs.push(lst(spaceStrs) + " ");
7247 return spaceStrs[n];
7248 }
7249
7250 function lst(arr) { return arr[arr.length-1]; }
7251
7252 var selectInput = function(node) { node.select(); };
7253 if (ios) // Mobile Safari apparently has a bug where select() is broken.
7254 selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
7255 else if (ie) // Suppress mysterious IE10 errors
7256 selectInput = function(node) { try { node.select(); } catch(_e) {} };
7257
7258 function indexOf(array, elt) {
7259 for (var i = 0; i < array.length; ++i)
7260 if (array[i] == elt) return i;
7261 return -1;
7262 }
7263 if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
7264 function map(array, f) {
7265 var out = [];
7266 for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
7267 return out;
7268 }
7269 if ([].map) map = function(array, f) { return array.map(f); };
7270
7271 function createObj(base, props) {
7272 var inst;
7273 if (Object.create) {
7274 inst = Object.create(base);
7275 } else {
7276 var ctor = function() {};
7277 ctor.prototype = base;
7278 inst = new ctor();
7279 }
7280 if (props) copyObj(props, inst);
7281 return inst;
7282 };
7283
7284 function copyObj(obj, target, overwrite) {
7285 if (!target) target = {};
7286 for (var prop in obj)
7287 if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
7288 target[prop] = obj[prop];
7289 return target;
7290 }
7291
7292 function bind(f) {
7293 var args = Array.prototype.slice.call(arguments, 1);
7294 return function(){return f.apply(null, args);};
7295 }
7296
7297 var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
7298 var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
7299 return /\w/.test(ch) || ch > "\x80" &&
7300 (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
7301 };
7302 function isWordChar(ch, helper) {
7303 if (!helper) return isWordCharBasic(ch);
7304 if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
7305 return helper.test(ch);
7306 }
7307
7308 function isEmpty(obj) {
7309 for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
7310 return true;
7311 }
7312
7313 // Extending unicode characters. A series of a non-extending char +
7314 // any number of extending chars is treated as a single unit as far
7315 // as editing and measuring is concerned. This is not fully correct,
7316 // since some scripts/fonts/browsers also treat other configurations
7317 // of code points as a group.
7318 var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
7319 function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
7320
7321 // DOM UTILITIES
7322
7323 function elt(tag, content, className, style) {
7324 var e = document.createElement(tag);
7325 if (className) e.className = className;
7326 if (style) e.style.cssText = style;
7327 if (typeof content == "string") e.appendChild(document.createTextNode(content));
7328 else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
7329 return e;
7330 }
7331
7332 var range;
7333 if (document.createRange) range = function(node, start, end) {
7334 var r = document.createRange();
7335 r.setEnd(node, end);
7336 r.setStart(node, start);
7337 return r;
7338 };
7339 else range = function(node, start, end) {
7340 var r = document.body.createTextRange();
7341 r.moveToElementText(node.parentNode);
7342 r.collapse(true);
7343 r.moveEnd("character", end);
7344 r.moveStart("character", start);
7345 return r;
7346 };
7347
7348 function removeChildren(e) {
7349 for (var count = e.childNodes.length; count > 0; --count)
7350 e.removeChild(e.firstChild);
7351 return e;
7352 }
7353
7354 function removeChildrenAndAdd(parent, e) {
7355 return removeChildren(parent).appendChild(e);
7356 }
7357
7358 function contains(parent, child) {
7359 if (parent.contains)
7360 return parent.contains(child);
7361 while (child = child.parentNode)
7362 if (child == parent) return true;
7363 }
7364
7365 function activeElt() { return document.activeElement; }
7366 // Older versions of IE throws unspecified error when touching
7367 // document.activeElement in some cases (during loading, in iframe)
7368 if (ie && ie_version < 11) activeElt = function() {
7369 try { return document.activeElement; }
7370 catch(e) { return document.body; }
7371 };
7372
7373 function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); }
7374 function rmClass(node, cls) {
7375 var test = classTest(cls);
7376 if (test.test(node.className)) node.className = node.className.replace(test, "");
7377 }
7378 function addClass(node, cls) {
7379 if (!classTest(cls).test(node.className)) node.className += " " + cls;
7380 }
7381 function joinClasses(a, b) {
7382 var as = a.split(" ");
7383 for (var i = 0; i < as.length; i++)
7384 if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
7385 return b;
7386 }
7387
7388 // WINDOW-WIDE EVENTS
7389
7390 // These must be handled carefully, because naively registering a
7391 // handler for each editor will cause the editors to never be
7392 // garbage collected.
7393
7394 function forEachCodeMirror(f) {
7395 if (!document.body.getElementsByClassName) return;
7396 var byClass = document.body.getElementsByClassName("CodeMirror");
7397 for (var i = 0; i < byClass.length; i++) {
7398 var cm = byClass[i].CodeMirror;
7399 if (cm) f(cm);
7400 }
7401 }
7402
7403 var globalsRegistered = false;
7404 function ensureGlobalHandlers() {
7405 if (globalsRegistered) return;
7406 registerGlobalHandlers();
7407 globalsRegistered = true;
7408 }
7409 function registerGlobalHandlers() {
7410 // When the window resizes, we need to refresh active editors.
7411 var resizeTimer;
7412 on(window, "resize", function() {
7413 if (resizeTimer == null) resizeTimer = setTimeout(function() {
7414 resizeTimer = null;
7415 knownScrollbarWidth = null;
7416 forEachCodeMirror(onResize);
7417 }, 100);
7418 });
7419 // When the window loses focus, we want to show the editor as blurred
7420 on(window, "blur", function() {
7421 forEachCodeMirror(onBlur);
7422 });
7423 }
7424
7425 // FEATURE DETECTION
7426
7427 // Detect drag-and-drop
7428 var dragAndDrop = function() {
7429 // There is *some* kind of drag-and-drop support in IE6-8, but I
7430 // couldn't get it to work yet.
7431 if (ie && ie_version < 9) return false;
7432 var div = elt('div');
7433 return "draggable" in div || "dragDrop" in div;
7434 }();
7435
7436 var knownScrollbarWidth;
7437 function scrollbarWidth(measure) {
7438 if (knownScrollbarWidth != null) return knownScrollbarWidth;
7439 var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
7440 removeChildrenAndAdd(measure, test);
7441 if (test.offsetWidth)
7442 knownScrollbarWidth = test.offsetHeight - test.clientHeight;
7443 return knownScrollbarWidth || 0;
7444 }
7445
7446 var zwspSupported;
7447 function zeroWidthElement(measure) {
7448 if (zwspSupported == null) {
7449 var test = elt("span", "\u200b");
7450 removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
7451 if (measure.firstChild.offsetHeight != 0)
7452 zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
7453 }
7454 if (zwspSupported) return elt("span", "\u200b");
7455 else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
7456 }
7457
7458 // Feature-detect IE's crummy client rect reporting for bidi text
7459 var badBidiRects;
7460 function hasBadBidiRects(measure) {
7461 if (badBidiRects != null) return badBidiRects;
7462 var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
7463 var r0 = range(txt, 0, 1).getBoundingClientRect();
7464 if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
7465 var r1 = range(txt, 1, 2).getBoundingClientRect();
7466 return badBidiRects = (r1.right - r0.right < 3);
7467 }
7468
7469 // See if "".split is the broken IE version, if so, provide an
7470 // alternative way to split lines.
7471 var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
7472 var pos = 0, result = [], l = string.length;
7473 while (pos <= l) {
7474 var nl = string.indexOf("\n", pos);
7475 if (nl == -1) nl = string.length;
7476 var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
7477 var rt = line.indexOf("\r");
7478 if (rt != -1) {
7479 result.push(line.slice(0, rt));
7480 pos += rt + 1;
7481 } else {
7482 result.push(line);
7483 pos = nl + 1;
7484 }
7485 }
7486 return result;
7487 } : function(string){return string.split(/\r\n?|\n/);};
7488
7489 var hasSelection = window.getSelection ? function(te) {
7490 try { return te.selectionStart != te.selectionEnd; }
7491 catch(e) { return false; }
7492 } : function(te) {
7493 try {var range = te.ownerDocument.selection.createRange();}
7494 catch(e) {}
7495 if (!range || range.parentElement() != te) return false;
7496 return range.compareEndPoints("StartToEnd", range) != 0;
7497 };
7498
7499 var hasCopyEvent = (function() {
7500 var e = elt("div");
7501 if ("oncopy" in e) return true;
7502 e.setAttribute("oncopy", "return;");
7503 return typeof e.oncopy == "function";
7504 })();
7505
7506 var badZoomedRects = null;
7507 function hasBadZoomedRects(measure) {
7508 if (badZoomedRects != null) return badZoomedRects;
7509 var node = removeChildrenAndAdd(measure, elt("span", "x"));
7510 var normal = node.getBoundingClientRect();
7511 var fromRange = range(node, 0, 1).getBoundingClientRect();
7512 return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
7513 }
7514
7515 // KEY NAMES
7516
7517 var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
7518 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
7519 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
7520 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
7521 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
7522 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
7523 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
7524 CodeMirror.keyNames = keyNames;
7525 (function() {
7526 // Number keys
7527 for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
7528 // Alphabetic keys
7529 for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
7530 // Function keys
7531 for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
7532 })();
7533
7534 // BIDI HELPERS
7535
7536 function iterateBidiSections(order, from, to, f) {
7537 if (!order) return f(from, to, "ltr");
7538 var found = false;
7539 for (var i = 0; i < order.length; ++i) {
7540 var part = order[i];
7541 if (part.from < to && part.to > from || from == to && part.to == from) {
7542 f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
7543 found = true;
7544 }
7545 }
7546 if (!found) f(from, to, "ltr");
7547 }
7548
7549 function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
7550 function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
7551
7552 function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
7553 function lineRight(line) {
7554 var order = getOrder(line);
7555 if (!order) return line.text.length;
7556 return bidiRight(lst(order));
7557 }
7558
7559 function lineStart(cm, lineN) {
7560 var line = getLine(cm.doc, lineN);
7561 var visual = visualLine(line);
7562 if (visual != line) lineN = lineNo(visual);
7563 var order = getOrder(visual);
7564 var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
7565 return Pos(lineN, ch);
7566 }
7567 function lineEnd(cm, lineN) {
7568 var merged, line = getLine(cm.doc, lineN);
7569 while (merged = collapsedSpanAtEnd(line)) {
7570 line = merged.find(1, true).line;
7571 lineN = null;
7572 }
7573 var order = getOrder(line);
7574 var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
7575 return Pos(lineN == null ? lineNo(line) : lineN, ch);
7576 }
7577 function lineStartSmart(cm, pos) {
7578 var start = lineStart(cm, pos.line);
7579 var line = getLine(cm.doc, start.line);
7580 var order = getOrder(line);
7581 if (!order || order[0].level == 0) {
7582 var firstNonWS = Math.max(0, line.text.search(/\S/));
7583 var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
7584 return Pos(start.line, inWS ? 0 : firstNonWS);
7585 }
7586 return start;
7587 }
7588
7589 function compareBidiLevel(order, a, b) {
7590 var linedir = order[0].level;
7591 if (a == linedir) return true;
7592 if (b == linedir) return false;
7593 return a < b;
7594 }
7595 var bidiOther;
7596 function getBidiPartAt(order, pos) {
7597 bidiOther = null;
7598 for (var i = 0, found; i < order.length; ++i) {
7599 var cur = order[i];
7600 if (cur.from < pos && cur.to > pos) return i;
7601 if ((cur.from == pos || cur.to == pos)) {
7602 if (found == null) {
7603 found = i;
7604 } else if (compareBidiLevel(order, cur.level, order[found].level)) {
7605 if (cur.from != cur.to) bidiOther = found;
7606 return i;
7607 } else {
7608 if (cur.from != cur.to) bidiOther = i;
7609 return found;
7610 }
7611 }
7612 }
7613 return found;
7614 }
7615
7616 function moveInLine(line, pos, dir, byUnit) {
7617 if (!byUnit) return pos + dir;
7618 do pos += dir;
7619 while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
7620 return pos;
7621 }
7622
7623 // This is needed in order to move 'visually' through bi-directional
7624 // text -- i.e., pressing left should make the cursor go left, even
7625 // when in RTL text. The tricky part is the 'jumps', where RTL and
7626 // LTR text touch each other. This often requires the cursor offset
7627 // to move more than one unit, in order to visually move one unit.
7628 function moveVisually(line, start, dir, byUnit) {
7629 var bidi = getOrder(line);
7630 if (!bidi) return moveLogically(line, start, dir, byUnit);
7631 var pos = getBidiPartAt(bidi, start), part = bidi[pos];
7632 var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
7633
7634 for (;;) {
7635 if (target > part.from && target < part.to) return target;
7636 if (target == part.from || target == part.to) {
7637 if (getBidiPartAt(bidi, target) == pos) return target;
7638 part = bidi[pos += dir];
7639 return (dir > 0) == part.level % 2 ? part.to : part.from;
7640 } else {
7641 part = bidi[pos += dir];
7642 if (!part) return null;
7643 if ((dir > 0) == part.level % 2)
7644 target = moveInLine(line, part.to, -1, byUnit);
7645 else
7646 target = moveInLine(line, part.from, 1, byUnit);
7647 }
7648 }
7649 }
7650
7651 function moveLogically(line, start, dir, byUnit) {
7652 var target = start + dir;
7653 if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
7654 return target < 0 || target > line.text.length ? null : target;
7655 }
7656
7657 // Bidirectional ordering algorithm
7658 // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
7659 // that this (partially) implements.
7660
7661 // One-char codes used for character types:
7662 // L (L): Left-to-Right
7663 // R (R): Right-to-Left
7664 // r (AL): Right-to-Left Arabic
7665 // 1 (EN): European Number
7666 // + (ES): European Number Separator
7667 // % (ET): European Number Terminator
7668 // n (AN): Arabic Number
7669 // , (CS): Common Number Separator
7670 // m (NSM): Non-Spacing Mark
7671 // b (BN): Boundary Neutral
7672 // s (B): Paragraph Separator
7673 // t (S): Segment Separator
7674 // w (WS): Whitespace
7675 // N (ON): Other Neutrals
7676
7677 // Returns null if characters are ordered as they appear
7678 // (left-to-right), or an array of sections ({from, to, level}
7679 // objects) in the order in which they occur visually.
7680 var bidiOrdering = (function() {
7681 // Character types for codepoints 0 to 0xff
7682 var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
7683 // Character types for codepoints 0x600 to 0x6ff
7684 var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
7685 function charType(code) {
7686 if (code <= 0xf7) return lowTypes.charAt(code);
7687 else if (0x590 <= code && code <= 0x5f4) return "R";
7688 else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
7689 else if (0x6ee <= code && code <= 0x8ac) return "r";
7690 else if (0x2000 <= code && code <= 0x200b) return "w";
7691 else if (code == 0x200c) return "b";
7692 else return "L";
7693 }
7694
7695 var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
7696 var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
7697 // Browsers seem to always treat the boundaries of block elements as being L.
7698 var outerType = "L";
7699
7700 function BidiSpan(level, from, to) {
7701 this.level = level;
7702 this.from = from; this.to = to;
7703 }
7704
7705 return function(str) {
7706 if (!bidiRE.test(str)) return false;
7707 var len = str.length, types = [];
7708 for (var i = 0, type; i < len; ++i)
7709 types.push(type = charType(str.charCodeAt(i)));
7710
7711 // W1. Examine each non-spacing mark (NSM) in the level run, and
7712 // change the type of the NSM to the type of the previous
7713 // character. If the NSM is at the start of the level run, it will
7714 // get the type of sor.
7715 for (var i = 0, prev = outerType; i < len; ++i) {
7716 var type = types[i];
7717 if (type == "m") types[i] = prev;
7718 else prev = type;
7719 }
7720
7721 // W2. Search backwards from each instance of a European number
7722 // until the first strong type (R, L, AL, or sor) is found. If an
7723 // AL is found, change the type of the European number to Arabic
7724 // number.
7725 // W3. Change all ALs to R.
7726 for (var i = 0, cur = outerType; i < len; ++i) {
7727 var type = types[i];
7728 if (type == "1" && cur == "r") types[i] = "n";
7729 else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
7730 }
7731
7732 // W4. A single European separator between two European numbers
7733 // changes to a European number. A single common separator between
7734 // two numbers of the same type changes to that type.
7735 for (var i = 1, prev = types[0]; i < len - 1; ++i) {
7736 var type = types[i];
7737 if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
7738 else if (type == "," && prev == types[i+1] &&
7739 (prev == "1" || prev == "n")) types[i] = prev;
7740 prev = type;
7741 }
7742
7743 // W5. A sequence of European terminators adjacent to European
7744 // numbers changes to all European numbers.
7745 // W6. Otherwise, separators and terminators change to Other
7746 // Neutral.
7747 for (var i = 0; i < len; ++i) {
7748 var type = types[i];
7749 if (type == ",") types[i] = "N";
7750 else if (type == "%") {
7751 for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
7752 var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
7753 for (var j = i; j < end; ++j) types[j] = replace;
7754 i = end - 1;
7755 }
7756 }
7757
7758 // W7. Search backwards from each instance of a European number
7759 // until the first strong type (R, L, or sor) is found. If an L is
7760 // found, then change the type of the European number to L.
7761 for (var i = 0, cur = outerType; i < len; ++i) {
7762 var type = types[i];
7763 if (cur == "L" && type == "1") types[i] = "L";
7764 else if (isStrong.test(type)) cur = type;
7765 }
7766
7767 // N1. A sequence of neutrals takes the direction of the
7768 // surrounding strong text if the text on both sides has the same
7769 // direction. European and Arabic numbers act as if they were R in
7770 // terms of their influence on neutrals. Start-of-level-run (sor)
7771 // and end-of-level-run (eor) are used at level run boundaries.
7772 // N2. Any remaining neutrals take the embedding direction.
7773 for (var i = 0; i < len; ++i) {
7774 if (isNeutral.test(types[i])) {
7775 for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
7776 var before = (i ? types[i-1] : outerType) == "L";
7777 var after = (end < len ? types[end] : outerType) == "L";
7778 var replace = before || after ? "L" : "R";
7779 for (var j = i; j < end; ++j) types[j] = replace;
7780 i = end - 1;
7781 }
7782 }
7783
7784 // Here we depart from the documented algorithm, in order to avoid
7785 // building up an actual levels array. Since there are only three
7786 // levels (0, 1, 2) in an implementation that doesn't take
7787 // explicit embedding into account, we can build up the order on
7788 // the fly, without following the level-based algorithm.
7789 var order = [], m;
7790 for (var i = 0; i < len;) {
7791 if (countsAsLeft.test(types[i])) {
7792 var start = i;
7793 for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
7794 order.push(new BidiSpan(0, start, i));
7795 } else {
7796 var pos = i, at = order.length;
7797 for (++i; i < len && types[i] != "L"; ++i) {}
7798 for (var j = pos; j < i;) {
7799 if (countsAsNum.test(types[j])) {
7800 if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
7801 var nstart = j;
7802 for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
7803 order.splice(at, 0, new BidiSpan(2, nstart, j));
7804 pos = j;
7805 } else ++j;
7806 }
7807 if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
7808 }
7809 }
7810 if (order[0].level == 1 && (m = str.match(/^\s+/))) {
7811 order[0].from = m[0].length;
7812 order.unshift(new BidiSpan(0, 0, m[0].length));
7813 }
7814 if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
7815 lst(order).to -= m[0].length;
7816 order.push(new BidiSpan(0, len - m[0].length, len));
7817 }
7818 if (order[0].level != lst(order).level)
7819 order.push(new BidiSpan(order[0].level, len, len));
7820
7821 return order;
7822 };
7823 })();
7824
7825 // THE END
7826
7827 CodeMirror.version = "4.7.0";
7828
7829 return CodeMirror;
7830 });
@@ -1,175 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("apl", function() {
15 var builtInOps = {
16 ".": "innerProduct",
17 "\\": "scan",
18 "/": "reduce",
19 "⌿": "reduce1Axis",
20 "⍀": "scan1Axis",
21 "¨": "each",
22 "⍣": "power"
23 };
24 var builtInFuncs = {
25 "+": ["conjugate", "add"],
26 "−": ["negate", "subtract"],
27 "×": ["signOf", "multiply"],
28 "÷": ["reciprocal", "divide"],
29 "⌈": ["ceiling", "greaterOf"],
30 "⌊": ["floor", "lesserOf"],
31 "∣": ["absolute", "residue"],
32 "⍳": ["indexGenerate", "indexOf"],
33 "?": ["roll", "deal"],
34 "⋆": ["exponentiate", "toThePowerOf"],
35 "⍟": ["naturalLog", "logToTheBase"],
36 "○": ["piTimes", "circularFuncs"],
37 "!": ["factorial", "binomial"],
38 "⌹": ["matrixInverse", "matrixDivide"],
39 "<": [null, "lessThan"],
40 "≤": [null, "lessThanOrEqual"],
41 "=": [null, "equals"],
42 ">": [null, "greaterThan"],
43 "≥": [null, "greaterThanOrEqual"],
44 "≠": [null, "notEqual"],
45 "≡": ["depth", "match"],
46 "≢": [null, "notMatch"],
47 "∈": ["enlist", "membership"],
48 "⍷": [null, "find"],
49 "∪": ["unique", "union"],
50 "∩": [null, "intersection"],
51 "∼": ["not", "without"],
52 "∨": [null, "or"],
53 "∧": [null, "and"],
54 "⍱": [null, "nor"],
55 "⍲": [null, "nand"],
56 "⍴": ["shapeOf", "reshape"],
57 ",": ["ravel", "catenate"],
58 "⍪": [null, "firstAxisCatenate"],
59 "⌽": ["reverse", "rotate"],
60 "⊖": ["axis1Reverse", "axis1Rotate"],
61 "⍉": ["transpose", null],
62 "↑": ["first", "take"],
63 "↓": [null, "drop"],
64 "⊂": ["enclose", "partitionWithAxis"],
65 "⊃": ["diclose", "pick"],
66 "⌷": [null, "index"],
67 "⍋": ["gradeUp", null],
68 "⍒": ["gradeDown", null],
69 "⊤": ["encode", null],
70 "⊥": ["decode", null],
71 "⍕": ["format", "formatByExample"],
72 "⍎": ["execute", null],
73 "⊣": ["stop", "left"],
74 "⊢": ["pass", "right"]
75 };
76
77 var isOperator = /[\.\/⌿⍀¨⍣]/;
78 var isNiladic = /⍬/;
79 var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/;
80 var isArrow = /←/;
81 var isComment = /[⍝#].*$/;
82
83 var stringEater = function(type) {
84 var prev;
85 prev = false;
86 return function(c) {
87 prev = c;
88 if (c === type) {
89 return prev === "\\";
90 }
91 return true;
92 };
93 };
94 return {
95 startState: function() {
96 return {
97 prev: false,
98 func: false,
99 op: false,
100 string: false,
101 escape: false
102 };
103 },
104 token: function(stream, state) {
105 var ch, funcName, word;
106 if (stream.eatSpace()) {
107 return null;
108 }
109 ch = stream.next();
110 if (ch === '"' || ch === "'") {
111 stream.eatWhile(stringEater(ch));
112 stream.next();
113 state.prev = true;
114 return "string";
115 }
116 if (/[\[{\(]/.test(ch)) {
117 state.prev = false;
118 return null;
119 }
120 if (/[\]}\)]/.test(ch)) {
121 state.prev = true;
122 return null;
123 }
124 if (isNiladic.test(ch)) {
125 state.prev = false;
126 return "niladic";
127 }
128 if (/[¯\d]/.test(ch)) {
129 if (state.func) {
130 state.func = false;
131 state.prev = false;
132 } else {
133 state.prev = true;
134 }
135 stream.eatWhile(/[\w\.]/);
136 return "number";
137 }
138 if (isOperator.test(ch)) {
139 return "operator apl-" + builtInOps[ch];
140 }
141 if (isArrow.test(ch)) {
142 return "apl-arrow";
143 }
144 if (isFunction.test(ch)) {
145 funcName = "apl-";
146 if (builtInFuncs[ch] != null) {
147 if (state.prev) {
148 funcName += builtInFuncs[ch][1];
149 } else {
150 funcName += builtInFuncs[ch][0];
151 }
152 }
153 state.func = true;
154 state.prev = false;
155 return "function " + funcName;
156 }
157 if (isComment.test(ch)) {
158 stream.skipToEnd();
159 return "comment";
160 }
161 if (ch === "∘" && stream.peek() === ".") {
162 stream.next();
163 return "function jot-dot";
164 }
165 stream.eatWhile(/[\w\$_]/);
166 word = stream.current();
167 state.prev = true;
168 return "keyword";
169 }
170 };
171 });
172
173 CodeMirror.defineMIME("text/apl", "apl");
174
175 });
@@ -1,198 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 * =====================================================================================
6 *
7 * Filename: mode/asterisk/asterisk.js
8 *
9 * Description: CodeMirror mode for Asterisk dialplan
10 *
11 * Created: 05/17/2012 09:20:25 PM
12 * Revision: none
13 *
14 * Author: Stas Kobzar (stas@modulis.ca),
15 * Company: Modulis.ca Inc.
16 *
17 * =====================================================================================
18 */
19
20 (function(mod) {
21 if (typeof exports == "object" && typeof module == "object") // CommonJS
22 mod(require("../../lib/codemirror"));
23 else if (typeof define == "function" && define.amd) // AMD
24 define(["../../lib/codemirror"], mod);
25 else // Plain browser env
26 mod(CodeMirror);
27 })(function(CodeMirror) {
28 "use strict";
29
30 CodeMirror.defineMode("asterisk", function() {
31 var atoms = ["exten", "same", "include","ignorepat","switch"],
32 dpcmd = ["#include","#exec"],
33 apps = [
34 "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi",
35 "alarmreceiver","amd","answer","authenticate","background","backgrounddetect",
36 "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent",
37 "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge",
38 "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge",
39 "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility",
40 "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa",
41 "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy",
42 "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif",
43 "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete",
44 "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus",
45 "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme",
46 "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete",
47 "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode",
48 "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish",
49 "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce",
50 "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones",
51 "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten",
52 "readfile","receivefax","receivefax","receivefax","record","removequeuemember",
53 "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun",
54 "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax",
55 "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags",
56 "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel",
57 "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground",
58 "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound",
59 "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor",
60 "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec",
61 "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate",
62 "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring",
63 "waitforsilence","waitmusiconhold","waituntil","while","zapateller"
64 ];
65
66 function basicToken(stream,state){
67 var cur = '';
68 var ch = '';
69 ch = stream.next();
70 // comment
71 if(ch == ";") {
72 stream.skipToEnd();
73 return "comment";
74 }
75 // context
76 if(ch == '[') {
77 stream.skipTo(']');
78 stream.eat(']');
79 return "header";
80 }
81 // string
82 if(ch == '"') {
83 stream.skipTo('"');
84 return "string";
85 }
86 if(ch == "'") {
87 stream.skipTo("'");
88 return "string-2";
89 }
90 // dialplan commands
91 if(ch == '#') {
92 stream.eatWhile(/\w/);
93 cur = stream.current();
94 if(dpcmd.indexOf(cur) !== -1) {
95 stream.skipToEnd();
96 return "strong";
97 }
98 }
99 // application args
100 if(ch == '$'){
101 var ch1 = stream.peek();
102 if(ch1 == '{'){
103 stream.skipTo('}');
104 stream.eat('}');
105 return "variable-3";
106 }
107 }
108 // extension
109 stream.eatWhile(/\w/);
110 cur = stream.current();
111 if(atoms.indexOf(cur) !== -1) {
112 state.extenStart = true;
113 switch(cur) {
114 case 'same': state.extenSame = true; break;
115 case 'include':
116 case 'switch':
117 case 'ignorepat':
118 state.extenInclude = true;break;
119 default:break;
120 }
121 return "atom";
122 }
123 }
124
125 return {
126 startState: function() {
127 return {
128 extenStart: false,
129 extenSame: false,
130 extenInclude: false,
131 extenExten: false,
132 extenPriority: false,
133 extenApplication: false
134 };
135 },
136 token: function(stream, state) {
137
138 var cur = '';
139 var ch = '';
140 if(stream.eatSpace()) return null;
141 // extension started
142 if(state.extenStart){
143 stream.eatWhile(/[^\s]/);
144 cur = stream.current();
145 if(/^=>?$/.test(cur)){
146 state.extenExten = true;
147 state.extenStart = false;
148 return "strong";
149 } else {
150 state.extenStart = false;
151 stream.skipToEnd();
152 return "error";
153 }
154 } else if(state.extenExten) {
155 // set exten and priority
156 state.extenExten = false;
157 state.extenPriority = true;
158 stream.eatWhile(/[^,]/);
159 if(state.extenInclude) {
160 stream.skipToEnd();
161 state.extenPriority = false;
162 state.extenInclude = false;
163 }
164 if(state.extenSame) {
165 state.extenPriority = false;
166 state.extenSame = false;
167 state.extenApplication = true;
168 }
169 return "tag";
170 } else if(state.extenPriority) {
171 state.extenPriority = false;
172 state.extenApplication = true;
173 ch = stream.next(); // get comma
174 if(state.extenSame) return null;
175 stream.eatWhile(/[^,]/);
176 return "number";
177 } else if(state.extenApplication) {
178 stream.eatWhile(/,/);
179 cur = stream.current();
180 if(cur === ',') return null;
181 stream.eatWhile(/\w/);
182 cur = stream.current().toLowerCase();
183 state.extenApplication = false;
184 if(apps.indexOf(cur) !== -1){
185 return "def strong";
186 }
187 } else{
188 return basicToken(stream,state);
189 }
190
191 return null;
192 }
193 };
194 });
195
196 CodeMirror.defineMIME("text/x-asterisk", "asterisk");
197
198 });
@@ -1,474 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("clike", function(config, parserConfig) {
15 var indentUnit = config.indentUnit,
16 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
17 dontAlignCalls = parserConfig.dontAlignCalls,
18 keywords = parserConfig.keywords || {},
19 builtin = parserConfig.builtin || {},
20 blockKeywords = parserConfig.blockKeywords || {},
21 atoms = parserConfig.atoms || {},
22 hooks = parserConfig.hooks || {},
23 multiLineStrings = parserConfig.multiLineStrings,
24 indentStatements = parserConfig.indentStatements !== false;
25 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
26
27 var curPunc;
28
29 function tokenBase(stream, state) {
30 var ch = stream.next();
31 if (hooks[ch]) {
32 var result = hooks[ch](stream, state);
33 if (result !== false) return result;
34 }
35 if (ch == '"' || ch == "'") {
36 state.tokenize = tokenString(ch);
37 return state.tokenize(stream, state);
38 }
39 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
40 curPunc = ch;
41 return null;
42 }
43 if (/\d/.test(ch)) {
44 stream.eatWhile(/[\w\.]/);
45 return "number";
46 }
47 if (ch == "/") {
48 if (stream.eat("*")) {
49 state.tokenize = tokenComment;
50 return tokenComment(stream, state);
51 }
52 if (stream.eat("/")) {
53 stream.skipToEnd();
54 return "comment";
55 }
56 }
57 if (isOperatorChar.test(ch)) {
58 stream.eatWhile(isOperatorChar);
59 return "operator";
60 }
61 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
62 var cur = stream.current();
63 if (keywords.propertyIsEnumerable(cur)) {
64 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
65 return "keyword";
66 }
67 if (builtin.propertyIsEnumerable(cur)) {
68 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
69 return "builtin";
70 }
71 if (atoms.propertyIsEnumerable(cur)) return "atom";
72 return "variable";
73 }
74
75 function tokenString(quote) {
76 return function(stream, state) {
77 var escaped = false, next, end = false;
78 while ((next = stream.next()) != null) {
79 if (next == quote && !escaped) {end = true; break;}
80 escaped = !escaped && next == "\\";
81 }
82 if (end || !(escaped || multiLineStrings))
83 state.tokenize = null;
84 return "string";
85 };
86 }
87
88 function tokenComment(stream, state) {
89 var maybeEnd = false, ch;
90 while (ch = stream.next()) {
91 if (ch == "/" && maybeEnd) {
92 state.tokenize = null;
93 break;
94 }
95 maybeEnd = (ch == "*");
96 }
97 return "comment";
98 }
99
100 function Context(indented, column, type, align, prev) {
101 this.indented = indented;
102 this.column = column;
103 this.type = type;
104 this.align = align;
105 this.prev = prev;
106 }
107 function pushContext(state, col, type) {
108 var indent = state.indented;
109 if (state.context && state.context.type == "statement")
110 indent = state.context.indented;
111 return state.context = new Context(indent, col, type, null, state.context);
112 }
113 function popContext(state) {
114 var t = state.context.type;
115 if (t == ")" || t == "]" || t == "}")
116 state.indented = state.context.indented;
117 return state.context = state.context.prev;
118 }
119
120 // Interface
121
122 return {
123 startState: function(basecolumn) {
124 return {
125 tokenize: null,
126 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
127 indented: 0,
128 startOfLine: true
129 };
130 },
131
132 token: function(stream, state) {
133 var ctx = state.context;
134 if (stream.sol()) {
135 if (ctx.align == null) ctx.align = false;
136 state.indented = stream.indentation();
137 state.startOfLine = true;
138 }
139 if (stream.eatSpace()) return null;
140 curPunc = null;
141 var style = (state.tokenize || tokenBase)(stream, state);
142 if (style == "comment" || style == "meta") return style;
143 if (ctx.align == null) ctx.align = true;
144
145 if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
146 else if (curPunc == "{") pushContext(state, stream.column(), "}");
147 else if (curPunc == "[") pushContext(state, stream.column(), "]");
148 else if (curPunc == "(") pushContext(state, stream.column(), ")");
149 else if (curPunc == "}") {
150 while (ctx.type == "statement") ctx = popContext(state);
151 if (ctx.type == "}") ctx = popContext(state);
152 while (ctx.type == "statement") ctx = popContext(state);
153 }
154 else if (curPunc == ctx.type) popContext(state);
155 else if (indentStatements &&
156 (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
157 (ctx.type == "statement" && curPunc == "newstatement")))
158 pushContext(state, stream.column(), "statement");
159 state.startOfLine = false;
160 return style;
161 },
162
163 indent: function(state, textAfter) {
164 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
165 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
166 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
167 var closing = firstChar == ctx.type;
168 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
169 else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
170 else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
171 else return ctx.indented + (closing ? 0 : indentUnit);
172 },
173
174 electricChars: "{}",
175 blockCommentStart: "/*",
176 blockCommentEnd: "*/",
177 lineComment: "//",
178 fold: "brace"
179 };
180 });
181
182 function words(str) {
183 var obj = {}, words = str.split(" ");
184 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
185 return obj;
186 }
187 var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
188 "double static else struct entry switch extern typedef float union for unsigned " +
189 "goto while enum void const signed volatile";
190
191 function cppHook(stream, state) {
192 if (!state.startOfLine) return false;
193 for (;;) {
194 if (stream.skipTo("\\")) {
195 stream.next();
196 if (stream.eol()) {
197 state.tokenize = cppHook;
198 break;
199 }
200 } else {
201 stream.skipToEnd();
202 state.tokenize = null;
203 break;
204 }
205 }
206 return "meta";
207 }
208
209 function cpp11StringHook(stream, state) {
210 stream.backUp(1);
211 // Raw strings.
212 if (stream.match(/(R|u8R|uR|UR|LR)/)) {
213 var match = stream.match(/"([^\s\\()]{0,16})\(/);
214 if (!match) {
215 return false;
216 }
217 state.cpp11RawStringDelim = match[1];
218 state.tokenize = tokenRawString;
219 return tokenRawString(stream, state);
220 }
221 // Unicode strings/chars.
222 if (stream.match(/(u8|u|U|L)/)) {
223 if (stream.match(/["']/, /* eat */ false)) {
224 return "string";
225 }
226 return false;
227 }
228 // Ignore this hook.
229 stream.next();
230 return false;
231 }
232
233 // C#-style strings where "" escapes a quote.
234 function tokenAtString(stream, state) {
235 var next;
236 while ((next = stream.next()) != null) {
237 if (next == '"' && !stream.eat('"')) {
238 state.tokenize = null;
239 break;
240 }
241 }
242 return "string";
243 }
244
245 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
246 // <delim> can be a string up to 16 characters long.
247 function tokenRawString(stream, state) {
248 // Escape characters that have special regex meanings.
249 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
250 var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
251 if (match)
252 state.tokenize = null;
253 else
254 stream.skipToEnd();
255 return "string";
256 }
257
258 function def(mimes, mode) {
259 if (typeof mimes == "string") mimes = [mimes];
260 var words = [];
261 function add(obj) {
262 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
263 words.push(prop);
264 }
265 add(mode.keywords);
266 add(mode.builtin);
267 add(mode.atoms);
268 if (words.length) {
269 mode.helperType = mimes[0];
270 CodeMirror.registerHelper("hintWords", mimes[0], words);
271 }
272
273 for (var i = 0; i < mimes.length; ++i)
274 CodeMirror.defineMIME(mimes[i], mode);
275 }
276
277 def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
278 name: "clike",
279 keywords: words(cKeywords),
280 blockKeywords: words("case do else for if switch while struct"),
281 atoms: words("null"),
282 hooks: {"#": cppHook},
283 modeProps: {fold: ["brace", "include"]}
284 });
285
286 def(["text/x-c++src", "text/x-c++hdr"], {
287 name: "clike",
288 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
289 "static_cast typeid catch operator template typename class friend private " +
290 "this using const_cast inline public throw virtual delete mutable protected " +
291 "wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
292 "static_assert override"),
293 blockKeywords: words("catch class do else finally for if struct switch try while"),
294 atoms: words("true false null"),
295 hooks: {
296 "#": cppHook,
297 "u": cpp11StringHook,
298 "U": cpp11StringHook,
299 "L": cpp11StringHook,
300 "R": cpp11StringHook
301 },
302 modeProps: {fold: ["brace", "include"]}
303 });
304
305 def("text/x-java", {
306 name: "clike",
307 keywords: words("abstract assert boolean break byte case catch char class const continue default " +
308 "do double else enum extends final finally float for goto if implements import " +
309 "instanceof int interface long native new package private protected public " +
310 "return short static strictfp super switch synchronized this throw throws transient " +
311 "try void volatile while"),
312 blockKeywords: words("catch class do else finally for if switch try while"),
313 atoms: words("true false null"),
314 hooks: {
315 "@": function(stream) {
316 stream.eatWhile(/[\w\$_]/);
317 return "meta";
318 }
319 },
320 modeProps: {fold: ["brace", "import"]}
321 });
322
323 def("text/x-csharp", {
324 name: "clike",
325 keywords: words("abstract as base break case catch checked class const continue" +
326 " default delegate do else enum event explicit extern finally fixed for" +
327 " foreach goto if implicit in interface internal is lock namespace new" +
328 " operator out override params private protected public readonly ref return sealed" +
329 " sizeof stackalloc static struct switch this throw try typeof unchecked" +
330 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
331 " global group into join let orderby partial remove select set value var yield"),
332 blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
333 builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
334 " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
335 " UInt64 bool byte char decimal double short int long object" +
336 " sbyte float string ushort uint ulong"),
337 atoms: words("true false null"),
338 hooks: {
339 "@": function(stream, state) {
340 if (stream.eat('"')) {
341 state.tokenize = tokenAtString;
342 return tokenAtString(stream, state);
343 }
344 stream.eatWhile(/[\w\$_]/);
345 return "meta";
346 }
347 }
348 });
349
350 function tokenTripleString(stream, state) {
351 var escaped = false;
352 while (!stream.eol()) {
353 if (!escaped && stream.match('"""')) {
354 state.tokenize = null;
355 break;
356 }
357 escaped = stream.next() != "\\" && !escaped;
358 }
359 return "string";
360 }
361
362 def("text/x-scala", {
363 name: "clike",
364 keywords: words(
365
366 /* scala */
367 "abstract case catch class def do else extends false final finally for forSome if " +
368 "implicit import lazy match new null object override package private protected return " +
369 "sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
370 "<% >: # @ " +
371
372 /* package scala */
373 "assert assume require print println printf readLine readBoolean readByte readShort " +
374 "readChar readInt readLong readFloat readDouble " +
375
376 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
377 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
378 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
379 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
380 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
381
382 /* package java.lang */
383 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
384 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
385 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
386 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
387 ),
388 multiLineStrings: true,
389 blockKeywords: words("catch class do else finally for forSome if match switch try while"),
390 atoms: words("true false null"),
391 indentStatements: false,
392 hooks: {
393 "@": function(stream) {
394 stream.eatWhile(/[\w\$_]/);
395 return "meta";
396 },
397 '"': function(stream, state) {
398 if (!stream.match('""')) return false;
399 state.tokenize = tokenTripleString;
400 return state.tokenize(stream, state);
401 }
402 }
403 });
404
405 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
406 name: "clike",
407 keywords: words("float int bool void " +
408 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
409 "mat2 mat3 mat4 " +
410 "sampler1D sampler2D sampler3D samplerCube " +
411 "sampler1DShadow sampler2DShadow" +
412 "const attribute uniform varying " +
413 "break continue discard return " +
414 "for while do if else struct " +
415 "in out inout"),
416 blockKeywords: words("for while do if else struct"),
417 builtin: words("radians degrees sin cos tan asin acos atan " +
418 "pow exp log exp2 sqrt inversesqrt " +
419 "abs sign floor ceil fract mod min max clamp mix step smootstep " +
420 "length distance dot cross normalize ftransform faceforward " +
421 "reflect refract matrixCompMult " +
422 "lessThan lessThanEqual greaterThan greaterThanEqual " +
423 "equal notEqual any all not " +
424 "texture1D texture1DProj texture1DLod texture1DProjLod " +
425 "texture2D texture2DProj texture2DLod texture2DProjLod " +
426 "texture3D texture3DProj texture3DLod texture3DProjLod " +
427 "textureCube textureCubeLod " +
428 "shadow1D shadow2D shadow1DProj shadow2DProj " +
429 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
430 "dFdx dFdy fwidth " +
431 "noise1 noise2 noise3 noise4"),
432 atoms: words("true false " +
433 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
434 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
435 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
436 "gl_FogCoord " +
437 "gl_Position gl_PointSize gl_ClipVertex " +
438 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
439 "gl_TexCoord gl_FogFragCoord " +
440 "gl_FragCoord gl_FrontFacing " +
441 "gl_FragColor gl_FragData gl_FragDepth " +
442 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
443 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
444 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
445 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
446 "gl_ProjectionMatrixInverseTranspose " +
447 "gl_ModelViewProjectionMatrixInverseTranspose " +
448 "gl_TextureMatrixInverseTranspose " +
449 "gl_NormalScale gl_DepthRange gl_ClipPlane " +
450 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
451 "gl_FrontLightModelProduct gl_BackLightModelProduct " +
452 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
453 "gl_FogParameters " +
454 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
455 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
456 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
457 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
458 "gl_MaxDrawBuffers"),
459 hooks: {"#": cppHook},
460 modeProps: {fold: ["brace", "include"]}
461 });
462
463 def("text/x-nesc", {
464 name: "clike",
465 keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
466 "implementation includes interface module new norace nx_struct nx_union post provides " +
467 "signal task uses abstract extends"),
468 blockKeywords: words("case do else for if switch while struct"),
469 atoms: words("null"),
470 hooks: {"#": cppHook},
471 modeProps: {fold: ["brace", "include"]}
472 });
473
474 });
@@ -1,243 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Author: Hans Engel
6 * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
7 */
8
9 (function(mod) {
10 if (typeof exports == "object" && typeof module == "object") // CommonJS
11 mod(require("../../lib/codemirror"));
12 else if (typeof define == "function" && define.amd) // AMD
13 define(["../../lib/codemirror"], mod);
14 else // Plain browser env
15 mod(CodeMirror);
16 })(function(CodeMirror) {
17 "use strict";
18
19 CodeMirror.defineMode("clojure", function (options) {
20 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
21 ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
22 var INDENT_WORD_SKIP = options.indentUnit || 2;
23 var NORMAL_INDENT_UNIT = options.indentUnit || 2;
24
25 function makeKeywords(str) {
26 var obj = {}, words = str.split(" ");
27 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
28 return obj;
29 }
30
31 var atoms = makeKeywords("true false nil");
32
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");
35
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->>");
38
39 var indentKeys = makeKeywords(
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 " +
42
43 // Binding forms
44 "let letfn binding loop for doseq dotimes when-let if-let " +
45
46 // Data structures
47 "defstruct struct-map assoc " +
48
49 // clojure.test
50 "testing deftest " +
51
52 // contrib
53 "handler-case handle dotrace deftrace");
54
55 var tests = {
56 digit: /\d/,
57 digit_or_colon: /[\d:]/,
58 hex: /[0-9a-f]/i,
59 sign: /[+-]/,
60 exponent: /e/i,
61 keyword_char: /[^\s\(\[\;\)\]]/,
62 symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/
63 };
64
65 function stateStack(indent, type, prev) { // represents a state stack object
66 this.indent = indent;
67 this.type = type;
68 this.prev = prev;
69 }
70
71 function pushStack(state, indent, type) {
72 state.indentStack = new stateStack(indent, type, state.indentStack);
73 }
74
75 function popStack(state) {
76 state.indentStack = state.indentStack.prev;
77 }
78
79 function isNumber(ch, stream){
80 // hex
81 if ( ch === '0' && stream.eat(/x/i) ) {
82 stream.eatWhile(tests.hex);
83 return true;
84 }
85
86 // leading sign
87 if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
88 stream.eat(tests.sign);
89 ch = stream.next();
90 }
91
92 if ( tests.digit.test(ch) ) {
93 stream.eat(ch);
94 stream.eatWhile(tests.digit);
95
96 if ( '.' == stream.peek() ) {
97 stream.eat('.');
98 stream.eatWhile(tests.digit);
99 }
100
101 if ( stream.eat(tests.exponent) ) {
102 stream.eat(tests.sign);
103 stream.eatWhile(tests.digit);
104 }
105
106 return true;
107 }
108
109 return false;
110 }
111
112 // Eat character that starts after backslash \
113 function eatCharacter(stream) {
114 var first = stream.next();
115 // Read special literals: backspace, newline, space, return.
116 // Just read all lowercase letters.
117 if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
118 return;
119 }
120 // Read unicode character: \u1000 \uA0a1
121 if (first === "u") {
122 stream.match(/[0-9a-z]{4}/i, true);
123 }
124 }
125
126 return {
127 startState: function () {
128 return {
129 indentStack: null,
130 indentation: 0,
131 mode: false
132 };
133 },
134
135 token: function (stream, state) {
136 if (state.indentStack == null && stream.sol()) {
137 // update indentation, but only if indentStack is empty
138 state.indentation = stream.indentation();
139 }
140
141 // skip spaces
142 if (stream.eatSpace()) {
143 return null;
144 }
145 var returnType = null;
146
147 switch(state.mode){
148 case "string": // multi-line string parsing mode
149 var next, escaped = false;
150 while ((next = stream.next()) != null) {
151 if (next == "\"" && !escaped) {
152
153 state.mode = false;
154 break;
155 }
156 escaped = !escaped && next == "\\";
157 }
158 returnType = STRING; // continue on in string mode
159 break;
160 default: // default parsing mode
161 var ch = stream.next();
162
163 if (ch == "\"") {
164 state.mode = "string";
165 returnType = STRING;
166 } else if (ch == "\\") {
167 eatCharacter(stream);
168 returnType = CHARACTER;
169 } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
170 returnType = ATOM;
171 } else if (ch == ";") { // comment
172 stream.skipToEnd(); // rest of the line is a comment
173 returnType = COMMENT;
174 } else if (isNumber(ch,stream)){
175 returnType = NUMBER;
176 } else if (ch == "(" || ch == "[" || ch == "{" ) {
177 var keyWord = '', indentTemp = stream.column(), letter;
178 /**
179 Either
180 (indent-word ..
181 (non-indent-word ..
182 (;something else, bracket, etc.
183 */
184
185 if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
186 keyWord += letter;
187 }
188
189 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
190 /^(?:def|with)/.test(keyWord))) { // indent-word
191 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
192 } else { // non-indent word
193 // we continue eating the spaces
194 stream.eatSpace();
195 if (stream.eol() || stream.peek() == ";") {
196 // nothing significant after
197 // we restart indentation the user defined spaces after
198 pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
199 } else {
200 pushStack(state, indentTemp + stream.current().length, ch); // else we match
201 }
202 }
203 stream.backUp(stream.current().length - 1); // undo all the eating
204
205 returnType = BRACKET;
206 } else if (ch == ")" || ch == "]" || ch == "}") {
207 returnType = BRACKET;
208 if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
209 popStack(state);
210 }
211 } else if ( ch == ":" ) {
212 stream.eatWhile(tests.symbol);
213 return ATOM;
214 } else {
215 stream.eatWhile(tests.symbol);
216
217 if (keywords && keywords.propertyIsEnumerable(stream.current())) {
218 returnType = KEYWORD;
219 } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
220 returnType = BUILTIN;
221 } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
222 returnType = ATOM;
223 } else {
224 returnType = VAR;
225 }
226 }
227 }
228
229 return returnType;
230 },
231
232 indent: function (state) {
233 if (state.indentStack == null) return state.indentation;
234 return state.indentStack.indent;
235 },
236
237 lineComment: ";;"
238 };
239 });
240
241 CodeMirror.defineMIME("text/x-clojure", "clojure");
242
243 });
@@ -1,255 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Author: Gautam Mehta
6 * Branched from CodeMirror's Scheme mode
7 */
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15 })(function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("cobol", function () {
19 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
20 ATOM = "atom", NUMBER = "number", KEYWORD = "keyword", MODTAG = "header",
21 COBOLLINENUM = "def", PERIOD = "link";
22 function makeKeywords(str) {
23 var obj = {}, words = str.split(" ");
24 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
25 return obj;
26 }
27 var atoms = makeKeywords("TRUE FALSE ZEROES ZEROS ZERO SPACES SPACE LOW-VALUE LOW-VALUES ");
28 var keywords = makeKeywords(
29 "ACCEPT ACCESS ACQUIRE ADD ADDRESS " +
30 "ADVANCING AFTER ALIAS ALL ALPHABET " +
31 "ALPHABETIC ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED " +
32 "ALSO ALTER ALTERNATE AND ANY " +
33 "ARE AREA AREAS ARITHMETIC ASCENDING " +
34 "ASSIGN AT ATTRIBUTE AUTHOR AUTO " +
35 "AUTO-SKIP AUTOMATIC B-AND B-EXOR B-LESS " +
36 "B-NOT B-OR BACKGROUND-COLOR BACKGROUND-COLOUR BEEP " +
37 "BEFORE BELL BINARY BIT BITS " +
38 "BLANK BLINK BLOCK BOOLEAN BOTTOM " +
39 "BY CALL CANCEL CD CF " +
40 "CH CHARACTER CHARACTERS CLASS CLOCK-UNITS " +
41 "CLOSE COBOL CODE CODE-SET COL " +
42 "COLLATING COLUMN COMMA COMMIT COMMITMENT " +
43 "COMMON COMMUNICATION COMP COMP-0 COMP-1 " +
44 "COMP-2 COMP-3 COMP-4 COMP-5 COMP-6 " +
45 "COMP-7 COMP-8 COMP-9 COMPUTATIONAL COMPUTATIONAL-0 " +
46 "COMPUTATIONAL-1 COMPUTATIONAL-2 COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 " +
47 "COMPUTATIONAL-6 COMPUTATIONAL-7 COMPUTATIONAL-8 COMPUTATIONAL-9 COMPUTE " +
48 "CONFIGURATION CONNECT CONSOLE CONTAINED CONTAINS " +
49 "CONTENT CONTINUE CONTROL CONTROL-AREA CONTROLS " +
50 "CONVERTING COPY CORR CORRESPONDING COUNT " +
51 "CRT CRT-UNDER CURRENCY CURRENT CURSOR " +
52 "DATA DATE DATE-COMPILED DATE-WRITTEN DAY " +
53 "DAY-OF-WEEK DB DB-ACCESS-CONTROL-KEY DB-DATA-NAME DB-EXCEPTION " +
54 "DB-FORMAT-NAME DB-RECORD-NAME DB-SET-NAME DB-STATUS DBCS " +
55 "DBCS-EDITED DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE " +
56 "DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING " +
57 "DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED " +
58 "DELIMITER DEPENDING DESCENDING DESCRIBED DESTINATION " +
59 "DETAIL DISABLE DISCONNECT DISPLAY DISPLAY-1 " +
60 "DISPLAY-2 DISPLAY-3 DISPLAY-4 DISPLAY-5 DISPLAY-6 " +
61 "DISPLAY-7 DISPLAY-8 DISPLAY-9 DIVIDE DIVISION " +
62 "DOWN DROP DUPLICATE DUPLICATES DYNAMIC " +
63 "EBCDIC EGI EJECT ELSE EMI " +
64 "EMPTY EMPTY-CHECK ENABLE END END. END-ACCEPT END-ACCEPT. " +
65 "END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY " +
66 "END-DIVIDE END-EVALUATE END-IF END-INVOKE END-MULTIPLY " +
67 "END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN " +
68 "END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT " +
69 "END-UNSTRING END-WRITE END-XML ENTER ENTRY " +
70 "ENVIRONMENT EOP EQUAL EQUALS ERASE " +
71 "ERROR ESI EVALUATE EVERY EXCEEDS " +
72 "EXCEPTION EXCLUSIVE EXIT EXTEND EXTERNAL " +
73 "EXTERNALLY-DESCRIBED-KEY FD FETCH FILE FILE-CONTROL " +
74 "FILE-STREAM FILES FILLER FINAL FIND " +
75 "FINISH FIRST FOOTING FOR FOREGROUND-COLOR " +
76 "FOREGROUND-COLOUR FORMAT FREE FROM FULL " +
77 "FUNCTION GENERATE GET GIVING GLOBAL " +
78 "GO GOBACK GREATER GROUP HEADING " +
79 "HIGH-VALUE HIGH-VALUES HIGHLIGHT I-O I-O-CONTROL " +
80 "ID IDENTIFICATION IF IN INDEX " +
81 "INDEX-1 INDEX-2 INDEX-3 INDEX-4 INDEX-5 " +
82 "INDEX-6 INDEX-7 INDEX-8 INDEX-9 INDEXED " +
83 "INDIC INDICATE INDICATOR INDICATORS INITIAL " +
84 "INITIALIZE INITIATE INPUT INPUT-OUTPUT INSPECT " +
85 "INSTALLATION INTO INVALID INVOKE IS " +
86 "JUST JUSTIFIED KANJI KEEP KEY " +
87 "LABEL LAST LD LEADING LEFT " +
88 "LEFT-JUSTIFY LENGTH LENGTH-CHECK LESS LIBRARY " +
89 "LIKE LIMIT LIMITS LINAGE LINAGE-COUNTER " +
90 "LINE LINE-COUNTER LINES LINKAGE LOCAL-STORAGE " +
91 "LOCALE LOCALLY LOCK " +
92 "MEMBER MEMORY MERGE MESSAGE METACLASS " +
93 "MODE MODIFIED MODIFY MODULES MOVE " +
94 "MULTIPLE MULTIPLY NATIONAL NATIVE NEGATIVE " +
95 "NEXT NO NO-ECHO NONE NOT " +
96 "NULL NULL-KEY-MAP NULL-MAP NULLS NUMBER " +
97 "NUMERIC NUMERIC-EDITED OBJECT OBJECT-COMPUTER OCCURS " +
98 "OF OFF OMITTED ON ONLY " +
99 "OPEN OPTIONAL OR ORDER ORGANIZATION " +
100 "OTHER OUTPUT OVERFLOW OWNER PACKED-DECIMAL " +
101 "PADDING PAGE PAGE-COUNTER PARSE PERFORM " +
102 "PF PH PIC PICTURE PLUS " +
103 "POINTER POSITION POSITIVE PREFIX PRESENT " +
104 "PRINTING PRIOR PROCEDURE PROCEDURE-POINTER PROCEDURES " +
105 "PROCEED PROCESS PROCESSING PROGRAM PROGRAM-ID " +
106 "PROMPT PROTECTED PURGE QUEUE QUOTE " +
107 "QUOTES RANDOM RD READ READY " +
108 "REALM RECEIVE RECONNECT RECORD RECORD-NAME " +
109 "RECORDS RECURSIVE REDEFINES REEL REFERENCE " +
110 "REFERENCE-MONITOR REFERENCES RELATION RELATIVE RELEASE " +
111 "REMAINDER REMOVAL RENAMES REPEATED REPLACE " +
112 "REPLACING REPORT REPORTING REPORTS REPOSITORY " +
113 "REQUIRED RERUN RESERVE RESET RETAINING " +
114 "RETRIEVAL RETURN RETURN-CODE RETURNING REVERSE-VIDEO " +
115 "REVERSED REWIND REWRITE RF RH " +
116 "RIGHT RIGHT-JUSTIFY ROLLBACK ROLLING ROUNDED " +
117 "RUN SAME SCREEN SD SEARCH " +
118 "SECTION SECURE SECURITY SEGMENT SEGMENT-LIMIT " +
119 "SELECT SEND SENTENCE SEPARATE SEQUENCE " +
120 "SEQUENTIAL SET SHARED SIGN SIZE " +
121 "SKIP1 SKIP2 SKIP3 SORT SORT-MERGE " +
122 "SORT-RETURN SOURCE SOURCE-COMPUTER SPACE-FILL " +
123 "SPECIAL-NAMES STANDARD STANDARD-1 STANDARD-2 " +
124 "START STARTING STATUS STOP STORE " +
125 "STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUB-SCHEMA " +
126 "SUBFILE SUBSTITUTE SUBTRACT SUM SUPPRESS " +
127 "SYMBOLIC SYNC SYNCHRONIZED SYSIN SYSOUT " +
128 "TABLE TALLYING TAPE TENANT TERMINAL " +
129 "TERMINATE TEST TEXT THAN THEN " +
130 "THROUGH THRU TIME TIMES TITLE " +
131 "TO TOP TRAILING TRAILING-SIGN TRANSACTION " +
132 "TYPE TYPEDEF UNDERLINE UNEQUAL UNIT " +
133 "UNSTRING UNTIL UP UPDATE UPON " +
134 "USAGE USAGE-MODE USE USING VALID " +
135 "VALIDATE VALUE VALUES VARYING VLR " +
136 "WAIT WHEN WHEN-COMPILED WITH WITHIN " +
137 "WORDS WORKING-STORAGE WRITE XML XML-CODE " +
138 "XML-EVENT XML-NTEXT XML-TEXT ZERO ZERO-FILL " );
139
140 var builtins = makeKeywords("- * ** / + < <= = > >= ");
141 var tests = {
142 digit: /\d/,
143 digit_or_colon: /[\d:]/,
144 hex: /[0-9a-f]/i,
145 sign: /[+-]/,
146 exponent: /e/i,
147 keyword_char: /[^\s\(\[\;\)\]]/,
148 symbol: /[\w*+\-]/
149 };
150 function isNumber(ch, stream){
151 // hex
152 if ( ch === '0' && stream.eat(/x/i) ) {
153 stream.eatWhile(tests.hex);
154 return true;
155 }
156 // leading sign
157 if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
158 stream.eat(tests.sign);
159 ch = stream.next();
160 }
161 if ( tests.digit.test(ch) ) {
162 stream.eat(ch);
163 stream.eatWhile(tests.digit);
164 if ( '.' == stream.peek()) {
165 stream.eat('.');
166 stream.eatWhile(tests.digit);
167 }
168 if ( stream.eat(tests.exponent) ) {
169 stream.eat(tests.sign);
170 stream.eatWhile(tests.digit);
171 }
172 return true;
173 }
174 return false;
175 }
176 return {
177 startState: function () {
178 return {
179 indentStack: null,
180 indentation: 0,
181 mode: false
182 };
183 },
184 token: function (stream, state) {
185 if (state.indentStack == null && stream.sol()) {
186 // update indentation, but only if indentStack is empty
187 state.indentation = 6 ; //stream.indentation();
188 }
189 // skip spaces
190 if (stream.eatSpace()) {
191 return null;
192 }
193 var returnType = null;
194 switch(state.mode){
195 case "string": // multi-line string parsing mode
196 var next = false;
197 while ((next = stream.next()) != null) {
198 if (next == "\"" || next == "\'") {
199 state.mode = false;
200 break;
201 }
202 }
203 returnType = STRING; // continue on in string mode
204 break;
205 default: // default parsing mode
206 var ch = stream.next();
207 var col = stream.column();
208 if (col >= 0 && col <= 5) {
209 returnType = COBOLLINENUM;
210 } else if (col >= 72 && col <= 79) {
211 stream.skipToEnd();
212 returnType = MODTAG;
213 } else if (ch == "*" && col == 6) { // comment
214 stream.skipToEnd(); // rest of the line is a comment
215 returnType = COMMENT;
216 } else if (ch == "\"" || ch == "\'") {
217 state.mode = "string";
218 returnType = STRING;
219 } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
220 returnType = ATOM;
221 } else if (ch == ".") {
222 returnType = PERIOD;
223 } else if (isNumber(ch,stream)){
224 returnType = NUMBER;
225 } else {
226 if (stream.current().match(tests.symbol)) {
227 while (col < 71) {
228 if (stream.eat(tests.symbol) === undefined) {
229 break;
230 } else {
231 col++;
232 }
233 }
234 }
235 if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
236 returnType = KEYWORD;
237 } else if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) {
238 returnType = BUILTIN;
239 } else if (atoms && atoms.propertyIsEnumerable(stream.current().toUpperCase())) {
240 returnType = ATOM;
241 } else returnType = null;
242 }
243 }
244 return returnType;
245 },
246 indent: function (state) {
247 if (state.indentStack == null) return state.indentation;
248 return state.indentStack.indent;
249 }
250 };
251 });
252
253 CodeMirror.defineMIME("text/x-cobol", "cobol");
254
255 });
@@ -1,369 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Link to the project's GitHub page:
6 * https://github.com/pickhardt/coffeescript-codemirror-mode
7 */
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15 })(function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("coffeescript", function(conf) {
19 var ERRORCLASS = "error";
20
21 function wordRegexp(words) {
22 return new RegExp("^((" + words.join(")|(") + "))\\b");
23 }
24
25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
27 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
28 var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
29
30 var wordOperators = wordRegexp(["and", "or", "not",
31 "is", "isnt", "in",
32 "instanceof", "typeof"]);
33 var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
34 "switch", "try", "catch", "finally", "class"];
35 var commonKeywords = ["break", "by", "continue", "debugger", "delete",
36 "do", "in", "of", "new", "return", "then",
37 "this", "@", "throw", "when", "until", "extends"];
38
39 var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
40
41 indentKeywords = wordRegexp(indentKeywords);
42
43
44 var stringPrefixes = /^('{3}|\"{3}|['\"])/;
45 var regexPrefixes = /^(\/{3}|\/)/;
46 var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
47 var constants = wordRegexp(commonConstants);
48
49 // Tokenizers
50 function tokenBase(stream, state) {
51 // Handle scope changes
52 if (stream.sol()) {
53 if (state.scope.align === null) state.scope.align = false;
54 var scopeOffset = state.scope.offset;
55 if (stream.eatSpace()) {
56 var lineOffset = stream.indentation();
57 if (lineOffset > scopeOffset && state.scope.type == "coffee") {
58 return "indent";
59 } else if (lineOffset < scopeOffset) {
60 return "dedent";
61 }
62 return null;
63 } else {
64 if (scopeOffset > 0) {
65 dedent(stream, state);
66 }
67 }
68 }
69 if (stream.eatSpace()) {
70 return null;
71 }
72
73 var ch = stream.peek();
74
75 // Handle docco title comment (single line)
76 if (stream.match("####")) {
77 stream.skipToEnd();
78 return "comment";
79 }
80
81 // Handle multi line comments
82 if (stream.match("###")) {
83 state.tokenize = longComment;
84 return state.tokenize(stream, state);
85 }
86
87 // Single line comment
88 if (ch === "#") {
89 stream.skipToEnd();
90 return "comment";
91 }
92
93 // Handle number literals
94 if (stream.match(/^-?[0-9\.]/, false)) {
95 var floatLiteral = false;
96 // Floats
97 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
98 floatLiteral = true;
99 }
100 if (stream.match(/^-?\d+\.\d*/)) {
101 floatLiteral = true;
102 }
103 if (stream.match(/^-?\.\d+/)) {
104 floatLiteral = true;
105 }
106
107 if (floatLiteral) {
108 // prevent from getting extra . on 1..
109 if (stream.peek() == "."){
110 stream.backUp(1);
111 }
112 return "number";
113 }
114 // Integers
115 var intLiteral = false;
116 // Hex
117 if (stream.match(/^-?0x[0-9a-f]+/i)) {
118 intLiteral = true;
119 }
120 // Decimal
121 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
122 intLiteral = true;
123 }
124 // Zero by itself with no other piece of number.
125 if (stream.match(/^-?0(?![\dx])/i)) {
126 intLiteral = true;
127 }
128 if (intLiteral) {
129 return "number";
130 }
131 }
132
133 // Handle strings
134 if (stream.match(stringPrefixes)) {
135 state.tokenize = tokenFactory(stream.current(), false, "string");
136 return state.tokenize(stream, state);
137 }
138 // Handle regex literals
139 if (stream.match(regexPrefixes)) {
140 if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
141 state.tokenize = tokenFactory(stream.current(), true, "string-2");
142 return state.tokenize(stream, state);
143 } else {
144 stream.backUp(1);
145 }
146 }
147
148 // Handle operators and delimiters
149 if (stream.match(operators) || stream.match(wordOperators)) {
150 return "operator";
151 }
152 if (stream.match(delimiters)) {
153 return "punctuation";
154 }
155
156 if (stream.match(constants)) {
157 return "atom";
158 }
159
160 if (stream.match(keywords)) {
161 return "keyword";
162 }
163
164 if (stream.match(identifiers)) {
165 return "variable";
166 }
167
168 if (stream.match(properties)) {
169 return "property";
170 }
171
172 // Handle non-detected items
173 stream.next();
174 return ERRORCLASS;
175 }
176
177 function tokenFactory(delimiter, singleline, outclass) {
178 return function(stream, state) {
179 while (!stream.eol()) {
180 stream.eatWhile(/[^'"\/\\]/);
181 if (stream.eat("\\")) {
182 stream.next();
183 if (singleline && stream.eol()) {
184 return outclass;
185 }
186 } else if (stream.match(delimiter)) {
187 state.tokenize = tokenBase;
188 return outclass;
189 } else {
190 stream.eat(/['"\/]/);
191 }
192 }
193 if (singleline) {
194 if (conf.mode.singleLineStringErrors) {
195 outclass = ERRORCLASS;
196 } else {
197 state.tokenize = tokenBase;
198 }
199 }
200 return outclass;
201 };
202 }
203
204 function longComment(stream, state) {
205 while (!stream.eol()) {
206 stream.eatWhile(/[^#]/);
207 if (stream.match("###")) {
208 state.tokenize = tokenBase;
209 break;
210 }
211 stream.eatWhile("#");
212 }
213 return "comment";
214 }
215
216 function indent(stream, state, type) {
217 type = type || "coffee";
218 var offset = 0, align = false, alignOffset = null;
219 for (var scope = state.scope; scope; scope = scope.prev) {
220 if (scope.type === "coffee" || scope.type == "}") {
221 offset = scope.offset + conf.indentUnit;
222 break;
223 }
224 }
225 if (type !== "coffee") {
226 align = null;
227 alignOffset = stream.column() + stream.current().length;
228 } else if (state.scope.align) {
229 state.scope.align = false;
230 }
231 state.scope = {
232 offset: offset,
233 type: type,
234 prev: state.scope,
235 align: align,
236 alignOffset: alignOffset
237 };
238 }
239
240 function dedent(stream, state) {
241 if (!state.scope.prev) return;
242 if (state.scope.type === "coffee") {
243 var _indent = stream.indentation();
244 var matched = false;
245 for (var scope = state.scope; scope; scope = scope.prev) {
246 if (_indent === scope.offset) {
247 matched = true;
248 break;
249 }
250 }
251 if (!matched) {
252 return true;
253 }
254 while (state.scope.prev && state.scope.offset !== _indent) {
255 state.scope = state.scope.prev;
256 }
257 return false;
258 } else {
259 state.scope = state.scope.prev;
260 return false;
261 }
262 }
263
264 function tokenLexer(stream, state) {
265 var style = state.tokenize(stream, state);
266 var current = stream.current();
267
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.
280 if (current === "return") {
281 state.dedent = true;
282 }
283 if (((current === "->" || current === "=>") &&
284 !state.lambda &&
285 !stream.peek())
286 || style === "indent") {
287 indent(stream, state);
288 }
289 var delimiter_index = "[({".indexOf(current);
290 if (delimiter_index !== -1) {
291 indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
292 }
293 if (indentKeywords.exec(current)){
294 indent(stream, state);
295 }
296 if (current == "then"){
297 dedent(stream, state);
298 }
299
300
301 if (style === "dedent") {
302 if (dedent(stream, state)) {
303 return ERRORCLASS;
304 }
305 }
306 delimiter_index = "])}".indexOf(current);
307 if (delimiter_index !== -1) {
308 while (state.scope.type == "coffee" && state.scope.prev)
309 state.scope = state.scope.prev;
310 if (state.scope.type == current)
311 state.scope = state.scope.prev;
312 }
313 if (state.dedent && stream.eol()) {
314 if (state.scope.type == "coffee" && state.scope.prev)
315 state.scope = state.scope.prev;
316 state.dedent = false;
317 }
318
319 return style;
320 }
321
322 var external = {
323 startState: function(basecolumn) {
324 return {
325 tokenize: tokenBase,
326 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
327 lastToken: null,
328 lambda: false,
329 dedent: 0
330 };
331 },
332
333 token: function(stream, state) {
334 var fillAlign = state.scope.align === null && state.scope;
335 if (fillAlign && stream.sol()) fillAlign.align = false;
336
337 var style = tokenLexer(stream, state);
338 if (fillAlign && style && style != "comment") fillAlign.align = true;
339
340 state.lastToken = {style:style, content: stream.current()};
341
342 if (stream.eol() && stream.lambda) {
343 state.lambda = false;
344 }
345
346 return style;
347 },
348
349 indent: function(state, text) {
350 if (state.tokenize != tokenBase) return 0;
351 var scope = state.scope;
352 var closer = text && "])}".indexOf(text.charAt(0)) > -1;
353 if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
354 var closes = closer && scope.type === text.charAt(0);
355 if (scope.align)
356 return scope.alignOffset - (closes ? 1 : 0);
357 else
358 return (closes ? scope.prev : scope).offset;
359 },
360
361 lineComment: "#",
362 fold: "indent"
363 };
364 return external;
365 });
366
367 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
368
369 });
@@ -1,120 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("commonlisp", function (config) {
15 var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/;
16 var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/;
17 var symbol = /[^\s'`,@()\[\]";]/;
18 var type;
19
20 function readSym(stream) {
21 var ch;
22 while (ch = stream.next()) {
23 if (ch == "\\") stream.next();
24 else if (!symbol.test(ch)) { stream.backUp(1); break; }
25 }
26 return stream.current();
27 }
28
29 function base(stream, state) {
30 if (stream.eatSpace()) {type = "ws"; return null;}
31 if (stream.match(numLiteral)) return "number";
32 var ch = stream.next();
33 if (ch == "\\") ch = stream.next();
34
35 if (ch == '"') return (state.tokenize = inString)(stream, state);
36 else if (ch == "(") { type = "open"; return "bracket"; }
37 else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; }
38 else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; }
39 else if (/['`,@]/.test(ch)) return null;
40 else if (ch == "|") {
41 if (stream.skipTo("|")) { stream.next(); return "symbol"; }
42 else { stream.skipToEnd(); return "error"; }
43 } else if (ch == "#") {
44 var ch = stream.next();
45 if (ch == "[") { type = "open"; return "bracket"; }
46 else if (/[+\-=\.']/.test(ch)) return null;
47 else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null;
48 else if (ch == "|") return (state.tokenize = inComment)(stream, state);
49 else if (ch == ":") { readSym(stream); return "meta"; }
50 else return "error";
51 } else {
52 var name = readSym(stream);
53 if (name == ".") return null;
54 type = "symbol";
55 if (name == "nil" || name == "t") return "atom";
56 if (name.charAt(0) == ":") return "keyword";
57 if (name.charAt(0) == "&") return "variable-2";
58 return "variable";
59 }
60 }
61
62 function inString(stream, state) {
63 var escaped = false, next;
64 while (next = stream.next()) {
65 if (next == '"' && !escaped) { state.tokenize = base; break; }
66 escaped = !escaped && next == "\\";
67 }
68 return "string";
69 }
70
71 function inComment(stream, state) {
72 var next, last;
73 while (next = stream.next()) {
74 if (next == "#" && last == "|") { state.tokenize = base; break; }
75 last = next;
76 }
77 type = "ws";
78 return "comment";
79 }
80
81 return {
82 startState: function () {
83 return {ctx: {prev: null, start: 0, indentTo: 0}, tokenize: base};
84 },
85
86 token: function (stream, state) {
87 if (stream.sol() && typeof state.ctx.indentTo != "number")
88 state.ctx.indentTo = state.ctx.start + 1;
89
90 type = null;
91 var style = state.tokenize(stream, state);
92 if (type != "ws") {
93 if (state.ctx.indentTo == null) {
94 if (type == "symbol" && assumeBody.test(stream.current()))
95 state.ctx.indentTo = state.ctx.start + config.indentUnit;
96 else
97 state.ctx.indentTo = "next";
98 } else if (state.ctx.indentTo == "next") {
99 state.ctx.indentTo = stream.column();
100 }
101 }
102 if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
103 else if (type == "close") state.ctx = state.ctx.prev || state.ctx;
104 return style;
105 },
106
107 indent: function (state, _textAfter) {
108 var i = state.ctx.indentTo;
109 return typeof i == "number" ? i : state.ctx.start + 1;
110 },
111
112 lineComment: ";;",
113 blockCommentStart: "#|",
114 blockCommentEnd: "|#"
115 };
116 });
117
118 CodeMirror.defineMIME("text/x-common-lisp", "commonlisp");
119
120 });
This diff has been collapsed as it changes many lines, (717 lines changed) Show them Hide them
@@ -1,717 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("css", function(config, parserConfig) {
15 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16
17 var indentUnit = config.indentUnit,
18 tokenHooks = parserConfig.tokenHooks,
19 mediaTypes = parserConfig.mediaTypes || {},
20 mediaFeatures = parserConfig.mediaFeatures || {},
21 propertyKeywords = parserConfig.propertyKeywords || {},
22 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
23 colorKeywords = parserConfig.colorKeywords || {},
24 valueKeywords = parserConfig.valueKeywords || {},
25 fontProperties = parserConfig.fontProperties || {},
26 allowNested = parserConfig.allowNested;
27
28 var type, override;
29 function ret(style, tp) { type = tp; return style; }
30
31 // Tokenizers
32
33 function tokenBase(stream, state) {
34 var ch = stream.next();
35 if (tokenHooks[ch]) {
36 var result = tokenHooks[ch](stream, state);
37 if (result !== false) return result;
38 }
39 if (ch == "@") {
40 stream.eatWhile(/[\w\\\-]/);
41 return ret("def", stream.current());
42 } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
43 return ret(null, "compare");
44 } else if (ch == "\"" || ch == "'") {
45 state.tokenize = tokenString(ch);
46 return state.tokenize(stream, state);
47 } else if (ch == "#") {
48 stream.eatWhile(/[\w\\\-]/);
49 return ret("atom", "hash");
50 } else if (ch == "!") {
51 stream.match(/^\s*\w*/);
52 return ret("keyword", "important");
53 } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
54 stream.eatWhile(/[\w.%]/);
55 return ret("number", "unit");
56 } else if (ch === "-") {
57 if (/[\d.]/.test(stream.peek())) {
58 stream.eatWhile(/[\w.%]/);
59 return ret("number", "unit");
60 } else if (stream.match(/^\w+-/)) {
61 return ret("meta", "meta");
62 }
63 } else if (/[,+>*\/]/.test(ch)) {
64 return ret(null, "select-op");
65 } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
66 return ret("qualifier", "qualifier");
67 } else if (/[:;{}\[\]\(\)]/.test(ch)) {
68 return ret(null, ch);
69 } else if (ch == "u" && stream.match("rl(")) {
70 stream.backUp(1);
71 state.tokenize = tokenParenthesized;
72 return ret("property", "word");
73 } else if (/[\w\\\-]/.test(ch)) {
74 stream.eatWhile(/[\w\\\-]/);
75 return ret("property", "word");
76 } else {
77 return ret(null, null);
78 }
79 }
80
81 function tokenString(quote) {
82 return function(stream, state) {
83 var escaped = false, ch;
84 while ((ch = stream.next()) != null) {
85 if (ch == quote && !escaped) {
86 if (quote == ")") stream.backUp(1);
87 break;
88 }
89 escaped = !escaped && ch == "\\";
90 }
91 if (ch == quote || !escaped && quote != ")") state.tokenize = null;
92 return ret("string", "string");
93 };
94 }
95
96 function tokenParenthesized(stream, state) {
97 stream.next(); // Must be '('
98 if (!stream.match(/\s*[\"\')]/, false))
99 state.tokenize = tokenString(")");
100 else
101 state.tokenize = null;
102 return ret(null, "(");
103 }
104
105 // Context management
106
107 function Context(type, indent, prev) {
108 this.type = type;
109 this.indent = indent;
110 this.prev = prev;
111 }
112
113 function pushContext(state, stream, type) {
114 state.context = new Context(type, stream.indentation() + indentUnit, state.context);
115 return type;
116 }
117
118 function popContext(state) {
119 state.context = state.context.prev;
120 return state.context.type;
121 }
122
123 function pass(type, stream, state) {
124 return states[state.context.type](type, stream, state);
125 }
126 function popAndPass(type, stream, state, n) {
127 for (var i = n || 1; i > 0; i--)
128 state.context = state.context.prev;
129 return pass(type, stream, state);
130 }
131
132 // Parser
133
134 function wordAsValue(stream) {
135 var word = stream.current().toLowerCase();
136 if (valueKeywords.hasOwnProperty(word))
137 override = "atom";
138 else if (colorKeywords.hasOwnProperty(word))
139 override = "keyword";
140 else
141 override = "variable";
142 }
143
144 var states = {};
145
146 states.top = function(type, stream, state) {
147 if (type == "{") {
148 return pushContext(state, stream, "block");
149 } else if (type == "}" && state.context.prev) {
150 return popContext(state);
151 } else if (type == "@media") {
152 return pushContext(state, stream, "media");
153 } else if (type == "@font-face") {
154 return "font_face_before";
155 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
156 return "keyframes";
157 } else if (type && type.charAt(0) == "@") {
158 return pushContext(state, stream, "at");
159 } else if (type == "hash") {
160 override = "builtin";
161 } else if (type == "word") {
162 override = "tag";
163 } else if (type == "variable-definition") {
164 return "maybeprop";
165 } else if (type == "interpolation") {
166 return pushContext(state, stream, "interpolation");
167 } else if (type == ":") {
168 return "pseudo";
169 } else if (allowNested && type == "(") {
170 return pushContext(state, stream, "parens");
171 }
172 return state.context.type;
173 };
174
175 states.block = function(type, stream, state) {
176 if (type == "word") {
177 var word = stream.current().toLowerCase();
178 if (propertyKeywords.hasOwnProperty(word)) {
179 override = "property";
180 return "maybeprop";
181 } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
182 override = "string-2";
183 return "maybeprop";
184 } else if (allowNested) {
185 override = stream.match(/^\s*:/, false) ? "property" : "tag";
186 return "block";
187 } else {
188 override += " error";
189 return "maybeprop";
190 }
191 } else if (type == "meta") {
192 return "block";
193 } else if (!allowNested && (type == "hash" || type == "qualifier")) {
194 override = "error";
195 return "block";
196 } else {
197 return states.top(type, stream, state);
198 }
199 };
200
201 states.maybeprop = function(type, stream, state) {
202 if (type == ":") return pushContext(state, stream, "prop");
203 return pass(type, stream, state);
204 };
205
206 states.prop = function(type, stream, state) {
207 if (type == ";") return popContext(state);
208 if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
209 if (type == "}" || type == "{") return popAndPass(type, stream, state);
210 if (type == "(") return pushContext(state, stream, "parens");
211
212 if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
213 override += " error";
214 } else if (type == "word") {
215 wordAsValue(stream);
216 } else if (type == "interpolation") {
217 return pushContext(state, stream, "interpolation");
218 }
219 return "prop";
220 };
221
222 states.propBlock = function(type, _stream, state) {
223 if (type == "}") return popContext(state);
224 if (type == "word") { override = "property"; return "maybeprop"; }
225 return state.context.type;
226 };
227
228 states.parens = function(type, stream, state) {
229 if (type == "{" || type == "}") return popAndPass(type, stream, state);
230 if (type == ")") return popContext(state);
231 if (type == "(") return pushContext(state, stream, "parens");
232 if (type == "word") wordAsValue(stream);
233 return "parens";
234 };
235
236 states.pseudo = function(type, stream, state) {
237 if (type == "word") {
238 override = "variable-3";
239 return state.context.type;
240 }
241 return pass(type, stream, state);
242 };
243
244 states.media = function(type, stream, state) {
245 if (type == "(") return pushContext(state, stream, "media_parens");
246 if (type == "}") return popAndPass(type, stream, state);
247 if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
248
249 if (type == "word") {
250 var word = stream.current().toLowerCase();
251 if (word == "only" || word == "not" || word == "and")
252 override = "keyword";
253 else if (mediaTypes.hasOwnProperty(word))
254 override = "attribute";
255 else if (mediaFeatures.hasOwnProperty(word))
256 override = "property";
257 else
258 override = "error";
259 }
260 return state.context.type;
261 };
262
263 states.media_parens = function(type, stream, state) {
264 if (type == ")") return popContext(state);
265 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
266 return states.media(type, stream, state);
267 };
268
269 states.font_face_before = function(type, stream, state) {
270 if (type == "{")
271 return pushContext(state, stream, "font_face");
272 return pass(type, stream, state);
273 };
274
275 states.font_face = function(type, stream, state) {
276 if (type == "}") return popContext(state);
277 if (type == "word") {
278 if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
279 override = "error";
280 else
281 override = "property";
282 return "maybeprop";
283 }
284 return "font_face";
285 };
286
287 states.keyframes = function(type, stream, state) {
288 if (type == "word") { override = "variable"; return "keyframes"; }
289 if (type == "{") return pushContext(state, stream, "top");
290 return pass(type, stream, state);
291 };
292
293 states.at = function(type, stream, state) {
294 if (type == ";") return popContext(state);
295 if (type == "{" || type == "}") return popAndPass(type, stream, state);
296 if (type == "word") override = "tag";
297 else if (type == "hash") override = "builtin";
298 return "at";
299 };
300
301 states.interpolation = function(type, stream, state) {
302 if (type == "}") return popContext(state);
303 if (type == "{" || type == ";") return popAndPass(type, stream, state);
304 if (type != "variable") override = "error";
305 return "interpolation";
306 };
307
308 return {
309 startState: function(base) {
310 return {tokenize: null,
311 state: "top",
312 context: new Context("top", base || 0, null)};
313 },
314
315 token: function(stream, state) {
316 if (!state.tokenize && stream.eatSpace()) return null;
317 var style = (state.tokenize || tokenBase)(stream, state);
318 if (style && typeof style == "object") {
319 type = style[1];
320 style = style[0];
321 }
322 override = style;
323 state.state = states[state.state](type, stream, state);
324 return override;
325 },
326
327 indent: function(state, textAfter) {
328 var cx = state.context, ch = textAfter && textAfter.charAt(0);
329 var indent = cx.indent;
330 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
331 if (cx.prev &&
332 (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
333 ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
334 ch == "{" && (cx.type == "at" || cx.type == "media"))) {
335 indent = cx.indent - indentUnit;
336 cx = cx.prev;
337 }
338 return indent;
339 },
340
341 electricChars: "}",
342 blockCommentStart: "/*",
343 blockCommentEnd: "*/",
344 fold: "brace"
345 };
346 });
347
348 function keySet(array) {
349 var keys = {};
350 for (var i = 0; i < array.length; ++i) {
351 keys[array[i]] = true;
352 }
353 return keys;
354 }
355
356 var mediaTypes_ = [
357 "all", "aural", "braille", "handheld", "print", "projection", "screen",
358 "tty", "tv", "embossed"
359 ], mediaTypes = keySet(mediaTypes_);
360
361 var mediaFeatures_ = [
362 "width", "min-width", "max-width", "height", "min-height", "max-height",
363 "device-width", "min-device-width", "max-device-width", "device-height",
364 "min-device-height", "max-device-height", "aspect-ratio",
365 "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
366 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
367 "max-color", "color-index", "min-color-index", "max-color-index",
368 "monochrome", "min-monochrome", "max-monochrome", "resolution",
369 "min-resolution", "max-resolution", "scan", "grid"
370 ], mediaFeatures = keySet(mediaFeatures_);
371
372 var propertyKeywords_ = [
373 "align-content", "align-items", "align-self", "alignment-adjust",
374 "alignment-baseline", "anchor-point", "animation", "animation-delay",
375 "animation-direction", "animation-duration", "animation-fill-mode",
376 "animation-iteration-count", "animation-name", "animation-play-state",
377 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
378 "background", "background-attachment", "background-clip", "background-color",
379 "background-image", "background-origin", "background-position",
380 "background-repeat", "background-size", "baseline-shift", "binding",
381 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
382 "bookmark-target", "border", "border-bottom", "border-bottom-color",
383 "border-bottom-left-radius", "border-bottom-right-radius",
384 "border-bottom-style", "border-bottom-width", "border-collapse",
385 "border-color", "border-image", "border-image-outset",
386 "border-image-repeat", "border-image-slice", "border-image-source",
387 "border-image-width", "border-left", "border-left-color",
388 "border-left-style", "border-left-width", "border-radius", "border-right",
389 "border-right-color", "border-right-style", "border-right-width",
390 "border-spacing", "border-style", "border-top", "border-top-color",
391 "border-top-left-radius", "border-top-right-radius", "border-top-style",
392 "border-top-width", "border-width", "bottom", "box-decoration-break",
393 "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
394 "caption-side", "clear", "clip", "color", "color-profile", "column-count",
395 "column-fill", "column-gap", "column-rule", "column-rule-color",
396 "column-rule-style", "column-rule-width", "column-span", "column-width",
397 "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
398 "cue-after", "cue-before", "cursor", "direction", "display",
399 "dominant-baseline", "drop-initial-after-adjust",
400 "drop-initial-after-align", "drop-initial-before-adjust",
401 "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
402 "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
403 "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
404 "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
405 "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
406 "font-stretch", "font-style", "font-synthesis", "font-variant",
407 "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
408 "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
409 "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
410 "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
411 "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
412 "grid-template", "grid-template-areas", "grid-template-columns",
413 "grid-template-rows", "hanging-punctuation", "height", "hyphens",
414 "icon", "image-orientation", "image-rendering", "image-resolution",
415 "inline-box-align", "justify-content", "left", "letter-spacing",
416 "line-break", "line-height", "line-stacking", "line-stacking-ruby",
417 "line-stacking-shift", "line-stacking-strategy", "list-style",
418 "list-style-image", "list-style-position", "list-style-type", "margin",
419 "margin-bottom", "margin-left", "margin-right", "margin-top",
420 "marker-offset", "marks", "marquee-direction", "marquee-loop",
421 "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
422 "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
423 "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
424 "opacity", "order", "orphans", "outline",
425 "outline-color", "outline-offset", "outline-style", "outline-width",
426 "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
427 "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
428 "page", "page-break-after", "page-break-before", "page-break-inside",
429 "page-policy", "pause", "pause-after", "pause-before", "perspective",
430 "perspective-origin", "pitch", "pitch-range", "play-during", "position",
431 "presentation-level", "punctuation-trim", "quotes", "region-break-after",
432 "region-break-before", "region-break-inside", "region-fragment",
433 "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
434 "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
435 "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
436 "shape-outside", "size", "speak", "speak-as", "speak-header",
437 "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
438 "tab-size", "table-layout", "target", "target-name", "target-new",
439 "target-position", "text-align", "text-align-last", "text-decoration",
440 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
441 "text-decoration-style", "text-emphasis", "text-emphasis-color",
442 "text-emphasis-position", "text-emphasis-style", "text-height",
443 "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
444 "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
445 "text-wrap", "top", "transform", "transform-origin", "transform-style",
446 "transition", "transition-delay", "transition-duration",
447 "transition-property", "transition-timing-function", "unicode-bidi",
448 "vertical-align", "visibility", "voice-balance", "voice-duration",
449 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
450 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
451 "word-spacing", "word-wrap", "z-index",
452 // SVG-specific
453 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
454 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
455 "color-interpolation", "color-interpolation-filters",
456 "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
457 "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
458 "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
459 "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
460 "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
461 "glyph-orientation-vertical", "text-anchor", "writing-mode"
462 ], propertyKeywords = keySet(propertyKeywords_);
463
464 var nonStandardPropertyKeywords_ = [
465 "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
466 "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
467 "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
468 "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
469 "searchfield-results-decoration", "zoom"
470 ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
471
472 var colorKeywords_ = [
473 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
474 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
475 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
476 "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
477 "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
478 "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
479 "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
480 "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
481 "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
482 "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
483 "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
484 "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
485 "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
486 "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
487 "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
488 "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
489 "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
490 "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
491 "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
492 "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
493 "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
494 "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
495 "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
496 "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
497 "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
498 "whitesmoke", "yellow", "yellowgreen"
499 ], colorKeywords = keySet(colorKeywords_);
500
501 var valueKeywords_ = [
502 "above", "absolute", "activeborder", "activecaption", "afar",
503 "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
504 "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
505 "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
506 "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
507 "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
508 "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
509 "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
510 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
511 "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
512 "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
513 "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
514 "content-box", "context-menu", "continuous", "copy", "cover", "crop",
515 "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
516 "decimal-leading-zero", "default", "default-button", "destination-atop",
517 "destination-in", "destination-out", "destination-over", "devanagari",
518 "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
519 "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
520 "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
521 "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
522 "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
523 "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
524 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
525 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
526 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
527 "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
528 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
529 "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
530 "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
531 "help", "hidden", "hide", "higher", "highlight", "highlighttext",
532 "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
533 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
534 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
535 "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
536 "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
537 "landscape", "lao", "large", "larger", "left", "level", "lighter",
538 "line-through", "linear", "lines", "list-item", "listbox", "listitem",
539 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
540 "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
541 "lower-roman", "lowercase", "ltr", "malayalam", "match",
542 "media-controls-background", "media-current-time-display",
543 "media-fullscreen-button", "media-mute-button", "media-play-button",
544 "media-return-to-realtime-button", "media-rewind-button",
545 "media-seek-back-button", "media-seek-forward-button", "media-slider",
546 "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
547 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
548 "menu", "menulist", "menulist-button", "menulist-text",
549 "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
550 "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
551 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
552 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
553 "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
554 "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
555 "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
556 "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
557 "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
558 "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
559 "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
560 "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
561 "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
562 "searchfield-cancel-button", "searchfield-decoration",
563 "searchfield-results-button", "searchfield-results-decoration",
564 "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
565 "single", "skip-white-space", "slide", "slider-horizontal",
566 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
567 "small", "small-caps", "small-caption", "smaller", "solid", "somali",
568 "source-atop", "source-in", "source-out", "source-over", "space", "square",
569 "square-button", "start", "static", "status-bar", "stretch", "stroke",
570 "sub", "subpixel-antialiased", "super", "sw-resize", "table",
571 "table-caption", "table-cell", "table-column", "table-column-group",
572 "table-footer-group", "table-header-group", "table-row", "table-row-group",
573 "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
574 "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
575 "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
576 "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
577 "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
578 "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
579 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
580 "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
581 "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
582 "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
583 "xx-large", "xx-small"
584 ], valueKeywords = keySet(valueKeywords_);
585
586 var fontProperties_ = [
587 "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
588 "font-stretch", "font-weight", "font-style"
589 ], fontProperties = keySet(fontProperties_);
590
591 var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
592 .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
593 CodeMirror.registerHelper("hintWords", "css", allWords);
594
595 function tokenCComment(stream, state) {
596 var maybeEnd = false, ch;
597 while ((ch = stream.next()) != null) {
598 if (maybeEnd && ch == "/") {
599 state.tokenize = null;
600 break;
601 }
602 maybeEnd = (ch == "*");
603 }
604 return ["comment", "comment"];
605 }
606
607 function tokenSGMLComment(stream, state) {
608 if (stream.skipTo("-->")) {
609 stream.match("-->");
610 state.tokenize = null;
611 } else {
612 stream.skipToEnd();
613 }
614 return ["comment", "comment"];
615 }
616
617 CodeMirror.defineMIME("text/css", {
618 mediaTypes: mediaTypes,
619 mediaFeatures: mediaFeatures,
620 propertyKeywords: propertyKeywords,
621 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
622 colorKeywords: colorKeywords,
623 valueKeywords: valueKeywords,
624 fontProperties: fontProperties,
625 tokenHooks: {
626 "<": function(stream, state) {
627 if (!stream.match("!--")) return false;
628 state.tokenize = tokenSGMLComment;
629 return tokenSGMLComment(stream, state);
630 },
631 "/": function(stream, state) {
632 if (!stream.eat("*")) return false;
633 state.tokenize = tokenCComment;
634 return tokenCComment(stream, state);
635 }
636 },
637 name: "css"
638 });
639
640 CodeMirror.defineMIME("text/x-scss", {
641 mediaTypes: mediaTypes,
642 mediaFeatures: mediaFeatures,
643 propertyKeywords: propertyKeywords,
644 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
645 colorKeywords: colorKeywords,
646 valueKeywords: valueKeywords,
647 fontProperties: fontProperties,
648 allowNested: true,
649 tokenHooks: {
650 "/": function(stream, state) {
651 if (stream.eat("/")) {
652 stream.skipToEnd();
653 return ["comment", "comment"];
654 } else if (stream.eat("*")) {
655 state.tokenize = tokenCComment;
656 return tokenCComment(stream, state);
657 } else {
658 return ["operator", "operator"];
659 }
660 },
661 ":": function(stream) {
662 if (stream.match(/\s*\{/))
663 return [null, "{"];
664 return false;
665 },
666 "$": function(stream) {
667 stream.match(/^[\w-]+/);
668 if (stream.match(/^\s*:/, false))
669 return ["variable-2", "variable-definition"];
670 return ["variable-2", "variable"];
671 },
672 "#": function(stream) {
673 if (!stream.eat("{")) return false;
674 return [null, "interpolation"];
675 }
676 },
677 name: "css",
678 helperType: "scss"
679 });
680
681 CodeMirror.defineMIME("text/x-less", {
682 mediaTypes: mediaTypes,
683 mediaFeatures: mediaFeatures,
684 propertyKeywords: propertyKeywords,
685 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
686 colorKeywords: colorKeywords,
687 valueKeywords: valueKeywords,
688 fontProperties: fontProperties,
689 allowNested: true,
690 tokenHooks: {
691 "/": function(stream, state) {
692 if (stream.eat("/")) {
693 stream.skipToEnd();
694 return ["comment", "comment"];
695 } else if (stream.eat("*")) {
696 state.tokenize = tokenCComment;
697 return tokenCComment(stream, state);
698 } else {
699 return ["operator", "operator"];
700 }
701 },
702 "@": function(stream) {
703 if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
704 stream.eatWhile(/[\w\\\-]/);
705 if (stream.match(/^\s*:/, false))
706 return ["variable-2", "variable-definition"];
707 return ["variable-2", "variable"];
708 },
709 "&": function() {
710 return ["atom", "atom"];
711 }
712 },
713 name: "css",
714 helperType: "less"
715 });
716
717 });
@@ -1,51 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function() {
5 "use strict";
6
7 var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
8 function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
9
10 MT("variable",
11 "[variable-2 @base]: [atom #f04615];",
12 "[qualifier .class] {",
13 " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
14 " [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
15 "}");
16
17 MT("amp",
18 "[qualifier .child], [qualifier .sibling] {",
19 " [qualifier .parent] [atom &] {",
20 " [property color]: [keyword black];",
21 " }",
22 " [atom &] + [atom &] {",
23 " [property color]: [keyword red];",
24 " }",
25 "}");
26
27 MT("mixin",
28 "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
29 " [property color]: [variable darken]([variable-2 @color], [number 10%]);",
30 "}",
31 "[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
32 " [property color]: [variable lighten]([variable-2 @color], [number 10%]);",
33 "}",
34 "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
35 " [property display]: [atom block];",
36 "}",
37 "[variable-2 @switch]: [variable light];",
38 "[qualifier .class] {",
39 " [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
40 "}");
41
42 MT("nest",
43 "[qualifier .one] {",
44 " [def @media] ([property width]: [number 400px]) {",
45 " [property font-size]: [number 1.2em];",
46 " [def @media] [attribute print] [keyword and] [property color] {",
47 " [property color]: [keyword blue];",
48 " }",
49 " }",
50 "}");
51 })();
@@ -1,110 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function() {
5 var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
6 function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
7
8 MT('url_with_quotation',
9 "[tag foo] { [property background]:[atom url]([string test.jpg]) }");
10
11 MT('url_with_double_quotes',
12 "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
13
14 MT('url_with_single_quotes',
15 "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
16
17 MT('string',
18 "[def @import] [string \"compass/css3\"]");
19
20 MT('important_keyword',
21 "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
22
23 MT('variable',
24 "[variable-2 $blue]:[atom #333]");
25
26 MT('variable_as_attribute',
27 "[tag foo] { [property color]:[variable-2 $blue] }");
28
29 MT('numbers',
30 "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
31
32 MT('number_percentage',
33 "[tag foo] { [property width]:[number 80%] }");
34
35 MT('selector',
36 "[builtin #hello][qualifier .world]{}");
37
38 MT('singleline_comment',
39 "[comment // this is a comment]");
40
41 MT('multiline_comment',
42 "[comment /*foobar*/]");
43
44 MT('attribute_with_hyphen',
45 "[tag foo] { [property font-size]:[number 10px] }");
46
47 MT('string_after_attribute',
48 "[tag foo] { [property content]:[string \"::\"] }");
49
50 MT('directives',
51 "[def @include] [qualifier .mixin]");
52
53 MT('basic_structure',
54 "[tag p] { [property background]:[keyword red]; }");
55
56 MT('nested_structure',
57 "[tag p] { [tag a] { [property color]:[keyword red]; } }");
58
59 MT('mixin',
60 "[def @mixin] [tag table-base] {}");
61
62 MT('number_without_semicolon',
63 "[tag p] {[property width]:[number 12]}",
64 "[tag a] {[property color]:[keyword red];}");
65
66 MT('atom_in_nested_block',
67 "[tag p] { [tag a] { [property color]:[atom #000]; } }");
68
69 MT('interpolation_in_property',
70 "[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
71
72 MT('interpolation_in_selector',
73 "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
74
75 MT('interpolation_error',
76 "[tag foo]#{[error foo]} { [property color]:[atom #000]; }");
77
78 MT("divide_operator",
79 "[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
80
81 MT('nested_structure_with_id_selector',
82 "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
83
84 MT('indent_mixin',
85 "[def @mixin] [tag container] (",
86 " [variable-2 $a]: [number 10],",
87 " [variable-2 $b]: [number 10])",
88 "{}");
89
90 MT('indent_nested',
91 "[tag foo] {",
92 " [tag bar] {",
93 " }",
94 "}");
95
96 MT('indent_parentheses',
97 "[tag foo] {",
98 " [property color]: [variable darken]([variable-2 $blue],",
99 " [number 9%]);",
100 "}");
101
102 MT('indent_vardef',
103 "[variable-2 $name]:",
104 " [string 'val'];",
105 "[tag tag] {",
106 " [tag inner] {",
107 " [property margin]: [number 3px];",
108 " }",
109 "}");
110 })();
@@ -1,146 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // By the Neo4j Team and contributors.
5 // https://github.com/neo4j-contrib/CodeMirror
6
7 (function(mod) {
8 if (typeof exports == "object" && typeof module == "object") // CommonJS
9 mod(require("../../lib/codemirror"));
10 else if (typeof define == "function" && define.amd) // AMD
11 define(["../../lib/codemirror"], mod);
12 else // Plain browser env
13 mod(CodeMirror);
14 })(function(CodeMirror) {
15 "use strict";
16 var wordRegexp = function(words) {
17 return new RegExp("^(?:" + words.join("|") + ")$", "i");
18 };
19
20 CodeMirror.defineMode("cypher", function(config) {
21 var tokenBase = function(stream/*, state*/) {
22 var ch = stream.next(), curPunc = null;
23 if (ch === "\"" || ch === "'") {
24 stream.match(/.+?["']/);
25 return "string";
26 }
27 if (/[{}\(\),\.;\[\]]/.test(ch)) {
28 curPunc = ch;
29 return "node";
30 } else if (ch === "/" && stream.eat("/")) {
31 stream.skipToEnd();
32 return "comment";
33 } else if (operatorChars.test(ch)) {
34 stream.eatWhile(operatorChars);
35 return null;
36 } else {
37 stream.eatWhile(/[_\w\d]/);
38 if (stream.eat(":")) {
39 stream.eatWhile(/[\w\d_\-]/);
40 return "atom";
41 }
42 var word = stream.current();
43 if (funcs.test(word)) return "builtin";
44 if (preds.test(word)) return "def";
45 if (keywords.test(word)) return "keyword";
46 return "variable";
47 }
48 };
49 var pushContext = function(state, type, col) {
50 return state.context = {
51 prev: state.context,
52 indent: state.indent,
53 col: col,
54 type: type
55 };
56 };
57 var popContext = function(state) {
58 state.indent = state.context.indent;
59 return state.context = state.context.prev;
60 };
61 var indentUnit = config.indentUnit;
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", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
64 var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
65 var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
66 var operatorChars = /[*+\-<>=&|~%^]/;
67
68 return {
69 startState: function(/*base*/) {
70 return {
71 tokenize: tokenBase,
72 context: null,
73 indent: 0,
74 col: 0
75 };
76 },
77 token: function(stream, state) {
78 if (stream.sol()) {
79 if (state.context && (state.context.align == null)) {
80 state.context.align = false;
81 }
82 state.indent = stream.indentation();
83 }
84 if (stream.eatSpace()) {
85 return null;
86 }
87 var style = state.tokenize(stream, state);
88 if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
89 state.context.align = true;
90 }
91 if (curPunc === "(") {
92 pushContext(state, ")", stream.column());
93 } else if (curPunc === "[") {
94 pushContext(state, "]", stream.column());
95 } else if (curPunc === "{") {
96 pushContext(state, "}", stream.column());
97 } else if (/[\]\}\)]/.test(curPunc)) {
98 while (state.context && state.context.type === "pattern") {
99 popContext(state);
100 }
101 if (state.context && curPunc === state.context.type) {
102 popContext(state);
103 }
104 } else if (curPunc === "." && state.context && state.context.type === "pattern") {
105 popContext(state);
106 } else if (/atom|string|variable/.test(style) && state.context) {
107 if (/[\}\]]/.test(state.context.type)) {
108 pushContext(state, "pattern", stream.column());
109 } else if (state.context.type === "pattern" && !state.context.align) {
110 state.context.align = true;
111 state.context.col = stream.column();
112 }
113 }
114 return style;
115 },
116 indent: function(state, textAfter) {
117 var firstChar = textAfter && textAfter.charAt(0);
118 var context = state.context;
119 if (/[\]\}]/.test(firstChar)) {
120 while (context && context.type === "pattern") {
121 context = context.prev;
122 }
123 }
124 var closing = context && firstChar === context.type;
125 if (!context) return 0;
126 if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
127 if (context.align) return context.col + (closing ? 0 : 1);
128 return context.indent + (closing ? 0 : indentUnit);
129 }
130 };
131 });
132
133 CodeMirror.modeExtensions["cypher"] = {
134 autoFormatLineBreaks: function(text) {
135 var i, lines, reProcessedPortion;
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;
138 for (var i = 0; i < lines.length; i++)
139 lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
140 return lines.join("\n");
141 }
142 };
143
144 CodeMirror.defineMIME("application/x-cypher-query", "cypher");
145
146 });
@@ -1,218 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("d", function(config, parserConfig) {
15 var indentUnit = config.indentUnit,
16 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
17 keywords = parserConfig.keywords || {},
18 builtin = parserConfig.builtin || {},
19 blockKeywords = parserConfig.blockKeywords || {},
20 atoms = parserConfig.atoms || {},
21 hooks = parserConfig.hooks || {},
22 multiLineStrings = parserConfig.multiLineStrings;
23 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
24
25 var curPunc;
26
27 function tokenBase(stream, state) {
28 var ch = stream.next();
29 if (hooks[ch]) {
30 var result = hooks[ch](stream, state);
31 if (result !== false) return result;
32 }
33 if (ch == '"' || ch == "'" || ch == "`") {
34 state.tokenize = tokenString(ch);
35 return state.tokenize(stream, state);
36 }
37 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
38 curPunc = ch;
39 return null;
40 }
41 if (/\d/.test(ch)) {
42 stream.eatWhile(/[\w\.]/);
43 return "number";
44 }
45 if (ch == "/") {
46 if (stream.eat("+")) {
47 state.tokenize = tokenComment;
48 return tokenNestedComment(stream, state);
49 }
50 if (stream.eat("*")) {
51 state.tokenize = tokenComment;
52 return tokenComment(stream, state);
53 }
54 if (stream.eat("/")) {
55 stream.skipToEnd();
56 return "comment";
57 }
58 }
59 if (isOperatorChar.test(ch)) {
60 stream.eatWhile(isOperatorChar);
61 return "operator";
62 }
63 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
64 var cur = stream.current();
65 if (keywords.propertyIsEnumerable(cur)) {
66 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
67 return "keyword";
68 }
69 if (builtin.propertyIsEnumerable(cur)) {
70 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
71 return "builtin";
72 }
73 if (atoms.propertyIsEnumerable(cur)) return "atom";
74 return "variable";
75 }
76
77 function tokenString(quote) {
78 return function(stream, state) {
79 var escaped = false, next, end = false;
80 while ((next = stream.next()) != null) {
81 if (next == quote && !escaped) {end = true; break;}
82 escaped = !escaped && next == "\\";
83 }
84 if (end || !(escaped || multiLineStrings))
85 state.tokenize = null;
86 return "string";
87 };
88 }
89
90 function tokenComment(stream, state) {
91 var maybeEnd = false, ch;
92 while (ch = stream.next()) {
93 if (ch == "/" && maybeEnd) {
94 state.tokenize = null;
95 break;
96 }
97 maybeEnd = (ch == "*");
98 }
99 return "comment";
100 }
101
102 function tokenNestedComment(stream, state) {
103 var maybeEnd = false, ch;
104 while (ch = stream.next()) {
105 if (ch == "/" && maybeEnd) {
106 state.tokenize = null;
107 break;
108 }
109 maybeEnd = (ch == "+");
110 }
111 return "comment";
112 }
113
114 function Context(indented, column, type, align, prev) {
115 this.indented = indented;
116 this.column = column;
117 this.type = type;
118 this.align = align;
119 this.prev = prev;
120 }
121 function pushContext(state, col, type) {
122 var indent = state.indented;
123 if (state.context && state.context.type == "statement")
124 indent = state.context.indented;
125 return state.context = new Context(indent, col, type, null, state.context);
126 }
127 function popContext(state) {
128 var t = state.context.type;
129 if (t == ")" || t == "]" || t == "}")
130 state.indented = state.context.indented;
131 return state.context = state.context.prev;
132 }
133
134 // Interface
135
136 return {
137 startState: function(basecolumn) {
138 return {
139 tokenize: null,
140 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
141 indented: 0,
142 startOfLine: true
143 };
144 },
145
146 token: function(stream, state) {
147 var ctx = state.context;
148 if (stream.sol()) {
149 if (ctx.align == null) ctx.align = false;
150 state.indented = stream.indentation();
151 state.startOfLine = true;
152 }
153 if (stream.eatSpace()) return null;
154 curPunc = null;
155 var style = (state.tokenize || tokenBase)(stream, state);
156 if (style == "comment" || style == "meta") return style;
157 if (ctx.align == null) ctx.align = true;
158
159 if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
160 else if (curPunc == "{") pushContext(state, stream.column(), "}");
161 else if (curPunc == "[") pushContext(state, stream.column(), "]");
162 else if (curPunc == "(") pushContext(state, stream.column(), ")");
163 else if (curPunc == "}") {
164 while (ctx.type == "statement") ctx = popContext(state);
165 if (ctx.type == "}") ctx = popContext(state);
166 while (ctx.type == "statement") ctx = popContext(state);
167 }
168 else if (curPunc == ctx.type) popContext(state);
169 else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
170 pushContext(state, stream.column(), "statement");
171 state.startOfLine = false;
172 return style;
173 },
174
175 indent: function(state, textAfter) {
176 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
177 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
178 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
179 var closing = firstChar == ctx.type;
180 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
181 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
182 else return ctx.indented + (closing ? 0 : indentUnit);
183 },
184
185 electricChars: "{}"
186 };
187 });
188
189 function words(str) {
190 var obj = {}, words = str.split(" ");
191 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
192 return obj;
193 }
194
195 var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
196 "out scope struct switch try union unittest version while with";
197
198 CodeMirror.defineMIME("text/x-d", {
199 name: "d",
200 keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
201 "debug default delegate delete deprecated export extern final finally function goto immutable " +
202 "import inout invariant is lazy macro module new nothrow override package pragma private " +
203 "protected public pure ref return shared short static super synchronized template this " +
204 "throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
205 blockKeywords),
206 blockKeywords: words(blockKeywords),
207 builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
208 "ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
209 atoms: words("exit failure success true false null"),
210 hooks: {
211 "@": function(stream, _state) {
212 stream.eatWhile(/[\w\$_]/);
213 return "meta";
214 }
215 }
216 });
217
218 });
@@ -1,47 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("diff", function() {
15
16 var TOKEN_NAMES = {
17 '+': 'positive',
18 '-': 'negative',
19 '@': 'meta'
20 };
21
22 return {
23 token: function(stream) {
24 var tw_pos = stream.string.search(/[\t ]+?$/);
25
26 if (!stream.sol() || tw_pos === 0) {
27 stream.skipToEnd();
28 return ("error " + (
29 TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
30 }
31
32 var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
33
34 if (tw_pos === -1) {
35 stream.skipToEnd();
36 } else {
37 stream.pos = tw_pos;
38 }
39
40 return token_name;
41 }
42 };
43 });
44
45 CodeMirror.defineMIME("text/x-diff", "diff");
46
47 });
@@ -1,67 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 require("../../addon/mode/overlay"));
8 else if (typeof define == "function" && define.amd) // AMD
9 define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 "../../addon/mode/overlay"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMode("django:inner", function() {
17 var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false",
18 "loop", "none", "self", "super", "if", "endif", "as", "not", "and",
19 "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
20 "ifnotequal", "endifnotequal", "extends", "include", "load", "length", "comment",
21 "endcomment", "empty"];
22 keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
23
24 function tokenBase (stream, state) {
25 stream.eatWhile(/[^\{]/);
26 var ch = stream.next();
27 if (ch == "{") {
28 if (ch = stream.eat(/\{|%|#/)) {
29 state.tokenize = inTag(ch);
30 return "tag";
31 }
32 }
33 }
34 function inTag (close) {
35 if (close == "{") {
36 close = "}";
37 }
38 return function (stream, state) {
39 var ch = stream.next();
40 if ((ch == close) && stream.eat("}")) {
41 state.tokenize = tokenBase;
42 return "tag";
43 }
44 if (stream.match(keywords)) {
45 return "keyword";
46 }
47 return close == "#" ? "comment" : "string";
48 };
49 }
50 return {
51 startState: function () {
52 return {tokenize: tokenBase};
53 },
54 token: function (stream, state) {
55 return state.tokenize(stream, state);
56 }
57 };
58 });
59
60 CodeMirror.defineMode("django", function(config) {
61 var htmlBase = CodeMirror.getMode(config, "text/html");
62 var djangoInner = CodeMirror.getMode(config, "django:inner");
63 return CodeMirror.overlayMode(htmlBase, djangoInner);
64 });
65
66 CodeMirror.defineMIME("text/x-django", "django");
67 });
@@ -1,142 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 DTD mode
6 Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
7 Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
8 GitHub: @peterkroon
9 */
10
11 (function(mod) {
12 if (typeof exports == "object" && typeof module == "object") // CommonJS
13 mod(require("../../lib/codemirror"));
14 else if (typeof define == "function" && define.amd) // AMD
15 define(["../../lib/codemirror"], mod);
16 else // Plain browser env
17 mod(CodeMirror);
18 })(function(CodeMirror) {
19 "use strict";
20
21 CodeMirror.defineMode("dtd", function(config) {
22 var indentUnit = config.indentUnit, type;
23 function ret(style, tp) {type = tp; return style;}
24
25 function tokenBase(stream, state) {
26 var ch = stream.next();
27
28 if (ch == "<" && stream.eat("!") ) {
29 if (stream.eatWhile(/[\-]/)) {
30 state.tokenize = tokenSGMLComment;
31 return tokenSGMLComment(stream, state);
32 } else if (stream.eatWhile(/[\w]/)) return ret("keyword", "doindent");
33 } else if (ch == "<" && stream.eat("?")) { //xml declaration
34 state.tokenize = inBlock("meta", "?>");
35 return ret("meta", ch);
36 } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
37 else if (ch == "|") return ret("keyword", "seperator");
38 else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
39 else if (ch.match(/[\[\]]/)) return ret("rule", ch);
40 else if (ch == "\"" || ch == "'") {
41 state.tokenize = tokenString(ch);
42 return state.tokenize(stream, state);
43 } else if (stream.eatWhile(/[a-zA-Z\?\+\d]/)) {
44 var sc = stream.current();
45 if( sc.substr(sc.length-1,sc.length).match(/\?|\+/) !== null )stream.backUp(1);
46 return ret("tag", "tag");
47 } else if (ch == "%" || ch == "*" ) return ret("number", "number");
48 else {
49 stream.eatWhile(/[\w\\\-_%.{,]/);
50 return ret(null, null);
51 }
52 }
53
54 function tokenSGMLComment(stream, state) {
55 var dashes = 0, ch;
56 while ((ch = stream.next()) != null) {
57 if (dashes >= 2 && ch == ">") {
58 state.tokenize = tokenBase;
59 break;
60 }
61 dashes = (ch == "-") ? dashes + 1 : 0;
62 }
63 return ret("comment", "comment");
64 }
65
66 function tokenString(quote) {
67 return function(stream, state) {
68 var escaped = false, ch;
69 while ((ch = stream.next()) != null) {
70 if (ch == quote && !escaped) {
71 state.tokenize = tokenBase;
72 break;
73 }
74 escaped = !escaped && ch == "\\";
75 }
76 return ret("string", "tag");
77 };
78 }
79
80 function inBlock(style, terminator) {
81 return function(stream, state) {
82 while (!stream.eol()) {
83 if (stream.match(terminator)) {
84 state.tokenize = tokenBase;
85 break;
86 }
87 stream.next();
88 }
89 return style;
90 };
91 }
92
93 return {
94 startState: function(base) {
95 return {tokenize: tokenBase,
96 baseIndent: base || 0,
97 stack: []};
98 },
99
100 token: function(stream, state) {
101 if (stream.eatSpace()) return null;
102 var style = state.tokenize(stream, state);
103
104 var context = state.stack[state.stack.length-1];
105 if (stream.current() == "[" || type === "doindent" || type == "[") state.stack.push("rule");
106 else if (type === "endtag") state.stack[state.stack.length-1] = "endtag";
107 else if (stream.current() == "]" || type == "]" || (type == ">" && context == "rule")) state.stack.pop();
108 else if (type == "[") state.stack.push("[");
109 return style;
110 },
111
112 indent: function(state, textAfter) {
113 var n = state.stack.length;
114
115 if( textAfter.match(/\]\s+|\]/) )n=n-1;
116 else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
117 if(textAfter.substr(0,1) === "<")n;
118 else if( type == "doindent" && textAfter.length > 1 )n;
119 else if( type == "doindent")n--;
120 else if( type == ">" && textAfter.length > 1)n;
121 else if( type == "tag" && textAfter !== ">")n;
122 else if( type == "tag" && state.stack[state.stack.length-1] == "rule")n--;
123 else if( type == "tag")n++;
124 else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule" && type === ">")n--;
125 else if( textAfter === ">" && state.stack[state.stack.length-1] == "rule")n;
126 else if( textAfter.substr(0,1) !== "<" && textAfter.substr(0,1) === ">" )n=n-1;
127 else if( textAfter === ">")n;
128 else n=n-1;
129 //over rule them all
130 if(type == null || type == "]")n--;
131 }
132
133 return state.baseIndent + n * indentUnit;
134 },
135
136 electricChars: "]>"
137 };
138 });
139
140 CodeMirror.defineMIME("application/xml-dtd", "dtd");
141
142 });
@@ -1,299 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("dylan", function(_config) {
15 // Words
16 var words = {
17 // Words that introduce unnamed definitions like "define interface"
18 unnamedDefinition: ["interface"],
19
20 // Words that introduce simple named definitions like "define library"
21 namedDefinition: ["module", "library", "macro",
22 "C-struct", "C-union",
23 "C-function", "C-callable-wrapper"
24 ],
25
26 // Words that introduce type definitions like "define class".
27 // These are also parameterized like "define method" and are
28 // appended to otherParameterizedDefinitionWords
29 typeParameterizedDefinition: ["class", "C-subtype", "C-mapped-subtype"],
30
31 // Words that introduce trickier definitions like "define method".
32 // These require special definitions to be added to startExpressions
33 otherParameterizedDefinition: ["method", "function",
34 "C-variable", "C-address"
35 ],
36
37 // Words that introduce module constant definitions.
38 // These must also be simple definitions and are
39 // appended to otherSimpleDefinitionWords
40 constantSimpleDefinition: ["constant"],
41
42 // Words that introduce module variable definitions.
43 // These must also be simple definitions and are
44 // appended to otherSimpleDefinitionWords
45 variableSimpleDefinition: ["variable"],
46
47 // Other words that introduce simple definitions
48 // (without implicit bodies).
49 otherSimpleDefinition: ["generic", "domain",
50 "C-pointer-type",
51 "table"
52 ],
53
54 // Words that begin statements with implicit bodies.
55 statement: ["if", "block", "begin", "method", "case",
56 "for", "select", "when", "unless", "until",
57 "while", "iterate", "profiling", "dynamic-bind"
58 ],
59
60 // Patterns that act as separators in compound statements.
61 // This may include any general pattern that must be indented
62 // specially.
63 separator: ["finally", "exception", "cleanup", "else",
64 "elseif", "afterwards"
65 ],
66
67 // Keywords that do not require special indentation handling,
68 // but which should be highlighted
69 other: ["above", "below", "by", "from", "handler", "in",
70 "instance", "let", "local", "otherwise", "slot",
71 "subclass", "then", "to", "keyed-by", "virtual"
72 ],
73
74 // Condition signaling function calls
75 signalingCalls: ["signal", "error", "cerror",
76 "break", "check-type", "abort"
77 ]
78 };
79
80 words["otherDefinition"] =
81 words["unnamedDefinition"]
82 .concat(words["namedDefinition"])
83 .concat(words["otherParameterizedDefinition"]);
84
85 words["definition"] =
86 words["typeParameterizedDefinition"]
87 .concat(words["otherDefinition"]);
88
89 words["parameterizedDefinition"] =
90 words["typeParameterizedDefinition"]
91 .concat(words["otherParameterizedDefinition"]);
92
93 words["simpleDefinition"] =
94 words["constantSimpleDefinition"]
95 .concat(words["variableSimpleDefinition"])
96 .concat(words["otherSimpleDefinition"]);
97
98 words["keyword"] =
99 words["statement"]
100 .concat(words["separator"])
101 .concat(words["other"]);
102
103 // Patterns
104 var symbolPattern = "[-_a-zA-Z?!*@<>$%]+";
105 var symbol = new RegExp("^" + symbolPattern);
106 var patterns = {
107 // Symbols with special syntax
108 symbolKeyword: symbolPattern + ":",
109 symbolClass: "<" + symbolPattern + ">",
110 symbolGlobal: "\\*" + symbolPattern + "\\*",
111 symbolConstant: "\\$" + symbolPattern
112 };
113 var patternStyles = {
114 symbolKeyword: "atom",
115 symbolClass: "tag",
116 symbolGlobal: "variable-2",
117 symbolConstant: "variable-3"
118 };
119
120 // Compile all patterns to regular expressions
121 for (var patternName in patterns)
122 if (patterns.hasOwnProperty(patternName))
123 patterns[patternName] = new RegExp("^" + patterns[patternName]);
124
125 // Names beginning "with-" and "without-" are commonly
126 // used as statement macro
127 patterns["keyword"] = [/^with(?:out)?-[-_a-zA-Z?!*@<>$%]+/];
128
129 var styles = {};
130 styles["keyword"] = "keyword";
131 styles["definition"] = "def";
132 styles["simpleDefinition"] = "def";
133 styles["signalingCalls"] = "builtin";
134
135 // protected words lookup table
136 var wordLookup = {};
137 var styleLookup = {};
138
139 [
140 "keyword",
141 "definition",
142 "simpleDefinition",
143 "signalingCalls"
144 ].forEach(function(type) {
145 words[type].forEach(function(word) {
146 wordLookup[word] = type;
147 styleLookup[word] = styles[type];
148 });
149 });
150
151
152 function chain(stream, state, f) {
153 state.tokenize = f;
154 return f(stream, state);
155 }
156
157 var type, content;
158
159 function ret(_type, style, _content) {
160 type = _type;
161 content = _content;
162 return style;
163 }
164
165 function tokenBase(stream, state) {
166 // String
167 var ch = stream.peek();
168 if (ch == "'" || ch == '"') {
169 stream.next();
170 return chain(stream, state, tokenString(ch, "string", "string"));
171 }
172 // Comment
173 else if (ch == "/") {
174 stream.next();
175 if (stream.eat("*")) {
176 return chain(stream, state, tokenComment);
177 } else if (stream.eat("/")) {
178 stream.skipToEnd();
179 return ret("comment", "comment");
180 } else {
181 stream.skipTo(" ");
182 return ret("operator", "operator");
183 }
184 }
185 // Decimal
186 else if (/\d/.test(ch)) {
187 stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
188 return ret("number", "number");
189 }
190 // Hash
191 else if (ch == "#") {
192 stream.next();
193 // Symbol with string syntax
194 ch = stream.peek();
195 if (ch == '"') {
196 stream.next();
197 return chain(stream, state, tokenString('"', "symbol", "string-2"));
198 }
199 // Binary number
200 else if (ch == "b") {
201 stream.next();
202 stream.eatWhile(/[01]/);
203 return ret("number", "number");
204 }
205 // Hex number
206 else if (ch == "x") {
207 stream.next();
208 stream.eatWhile(/[\da-f]/i);
209 return ret("number", "number");
210 }
211 // Octal number
212 else if (ch == "o") {
213 stream.next();
214 stream.eatWhile(/[0-7]/);
215 return ret("number", "number");
216 }
217 // Hash symbol
218 else {
219 stream.eatWhile(/[-a-zA-Z]/);
220 return ret("hash", "keyword");
221 }
222 } else if (stream.match("end")) {
223 return ret("end", "keyword");
224 }
225 for (var name in patterns) {
226 if (patterns.hasOwnProperty(name)) {
227 var pattern = patterns[name];
228 if ((pattern instanceof Array && pattern.some(function(p) {
229 return stream.match(p);
230 })) || stream.match(pattern))
231 return ret(name, patternStyles[name], stream.current());
232 }
233 }
234 if (stream.match("define")) {
235 return ret("definition", "def");
236 } else {
237 stream.eatWhile(/[\w\-]/);
238 // Keyword
239 if (wordLookup[stream.current()]) {
240 return ret(wordLookup[stream.current()], styleLookup[stream.current()], stream.current());
241 } else if (stream.current().match(symbol)) {
242 return ret("variable", "variable");
243 } else {
244 stream.next();
245 return ret("other", "variable-2");
246 }
247 }
248 }
249
250 function tokenComment(stream, state) {
251 var maybeEnd = false,
252 ch;
253 while ((ch = stream.next())) {
254 if (ch == "/" && maybeEnd) {
255 state.tokenize = tokenBase;
256 break;
257 }
258 maybeEnd = (ch == "*");
259 }
260 return ret("comment", "comment");
261 }
262
263 function tokenString(quote, type, style) {
264 return function(stream, state) {
265 var next, end = false;
266 while ((next = stream.next()) != null) {
267 if (next == quote) {
268 end = true;
269 break;
270 }
271 }
272 if (end)
273 state.tokenize = tokenBase;
274 return ret(type, style);
275 };
276 }
277
278 // Interface
279 return {
280 startState: function() {
281 return {
282 tokenize: tokenBase,
283 currentIndent: 0
284 };
285 },
286 token: function(stream, state) {
287 if (stream.eatSpace())
288 return null;
289 var style = state.tokenize(stream, state);
290 return style;
291 },
292 blockCommentStart: "/*",
293 blockCommentEnd: "*/"
294 };
295 });
296
297 CodeMirror.defineMIME("text/x-dylan", "dylan");
298
299 });
@@ -1,207 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("ecl", function(config) {
15
16 function words(str) {
17 var obj = {}, words = str.split(" ");
18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
19 return obj;
20 }
21
22 function metaHook(stream, state) {
23 if (!state.startOfLine) return false;
24 stream.skipToEnd();
25 return "meta";
26 }
27
28 var indentUnit = config.indentUnit;
29 var keyword = words("abs acos allnodes ascii asin asstring atan atan2 ave case choose choosen choosesets clustersize combine correlation cos cosh count covariance cron dataset dedup define denormalize distribute distributed distribution ebcdic enth error evaluate event eventextra eventname exists exp failcode failmessage fetch fromunicode getisvalid global graph group hash hash32 hash64 hashcrc hashmd5 having if index intformat isvalid iterate join keyunicode length library limit ln local log loop map matched matchlength matchposition matchtext matchunicode max merge mergejoin min nolocal nonempty normalize parse pipe power preload process project pull random range rank ranked realformat recordof regexfind regexreplace regroup rejected rollup round roundup row rowdiff sample set sin sinh sizeof soapcall sort sorted sqrt stepped stored sum table tan tanh thisnode topn tounicode transfer trim truncate typeof ungroup unicodeorder variance which workunit xmldecode xmlencode xmltext xmlunicode");
30 var variable = words("apply assert build buildindex evaluate fail keydiff keypatch loadxml nothor notify output parallel sequential soapcall wait");
31 var variable_2 = words("__compressed__ all and any as atmost before beginc++ best between case const counter csv descend encrypt end endc++ endmacro except exclusive expire export extend false few first flat from full function group header heading hole ifblock import in interface joined keep keyed last left limit load local locale lookup macro many maxcount maxlength min skew module named nocase noroot noscan nosort not of only opt or outer overwrite packed partition penalty physicallength pipe quote record relationship repeat return right scan self separator service shared skew skip sql store terminator thor threshold token transform trim true type unicodeorder unsorted validate virtual whole wild within xml xpath");
32 var variable_3 = words("ascii big_endian boolean data decimal ebcdic integer pattern qstring real record rule set of string token udecimal unicode unsigned varstring varunicode");
33 var builtin = words("checkpoint deprecated failcode failmessage failure global independent onwarning persist priority recovery stored success wait when");
34 var blockKeywords = words("catch class do else finally for if switch try while");
35 var atoms = words("true false null");
36 var hooks = {"#": metaHook};
37 var multiLineStrings;
38 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
39
40 var curPunc;
41
42 function tokenBase(stream, state) {
43 var ch = stream.next();
44 if (hooks[ch]) {
45 var result = hooks[ch](stream, state);
46 if (result !== false) return result;
47 }
48 if (ch == '"' || ch == "'") {
49 state.tokenize = tokenString(ch);
50 return state.tokenize(stream, state);
51 }
52 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
53 curPunc = ch;
54 return null;
55 }
56 if (/\d/.test(ch)) {
57 stream.eatWhile(/[\w\.]/);
58 return "number";
59 }
60 if (ch == "/") {
61 if (stream.eat("*")) {
62 state.tokenize = tokenComment;
63 return tokenComment(stream, state);
64 }
65 if (stream.eat("/")) {
66 stream.skipToEnd();
67 return "comment";
68 }
69 }
70 if (isOperatorChar.test(ch)) {
71 stream.eatWhile(isOperatorChar);
72 return "operator";
73 }
74 stream.eatWhile(/[\w\$_]/);
75 var cur = stream.current().toLowerCase();
76 if (keyword.propertyIsEnumerable(cur)) {
77 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
78 return "keyword";
79 } else if (variable.propertyIsEnumerable(cur)) {
80 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
81 return "variable";
82 } else if (variable_2.propertyIsEnumerable(cur)) {
83 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
84 return "variable-2";
85 } else if (variable_3.propertyIsEnumerable(cur)) {
86 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
87 return "variable-3";
88 } else if (builtin.propertyIsEnumerable(cur)) {
89 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
90 return "builtin";
91 } else { //Data types are of from KEYWORD##
92 var i = cur.length - 1;
93 while(i >= 0 && (!isNaN(cur[i]) || cur[i] == '_'))
94 --i;
95
96 if (i > 0) {
97 var cur2 = cur.substr(0, i + 1);
98 if (variable_3.propertyIsEnumerable(cur2)) {
99 if (blockKeywords.propertyIsEnumerable(cur2)) curPunc = "newstatement";
100 return "variable-3";
101 }
102 }
103 }
104 if (atoms.propertyIsEnumerable(cur)) return "atom";
105 return null;
106 }
107
108 function tokenString(quote) {
109 return function(stream, state) {
110 var escaped = false, next, end = false;
111 while ((next = stream.next()) != null) {
112 if (next == quote && !escaped) {end = true; break;}
113 escaped = !escaped && next == "\\";
114 }
115 if (end || !(escaped || multiLineStrings))
116 state.tokenize = tokenBase;
117 return "string";
118 };
119 }
120
121 function tokenComment(stream, state) {
122 var maybeEnd = false, ch;
123 while (ch = stream.next()) {
124 if (ch == "/" && maybeEnd) {
125 state.tokenize = tokenBase;
126 break;
127 }
128 maybeEnd = (ch == "*");
129 }
130 return "comment";
131 }
132
133 function Context(indented, column, type, align, prev) {
134 this.indented = indented;
135 this.column = column;
136 this.type = type;
137 this.align = align;
138 this.prev = prev;
139 }
140 function pushContext(state, col, type) {
141 return state.context = new Context(state.indented, col, type, null, state.context);
142 }
143 function popContext(state) {
144 var t = state.context.type;
145 if (t == ")" || t == "]" || t == "}")
146 state.indented = state.context.indented;
147 return state.context = state.context.prev;
148 }
149
150 // Interface
151
152 return {
153 startState: function(basecolumn) {
154 return {
155 tokenize: null,
156 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
157 indented: 0,
158 startOfLine: true
159 };
160 },
161
162 token: function(stream, state) {
163 var ctx = state.context;
164 if (stream.sol()) {
165 if (ctx.align == null) ctx.align = false;
166 state.indented = stream.indentation();
167 state.startOfLine = true;
168 }
169 if (stream.eatSpace()) return null;
170 curPunc = null;
171 var style = (state.tokenize || tokenBase)(stream, state);
172 if (style == "comment" || style == "meta") return style;
173 if (ctx.align == null) ctx.align = true;
174
175 if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
176 else if (curPunc == "{") pushContext(state, stream.column(), "}");
177 else if (curPunc == "[") pushContext(state, stream.column(), "]");
178 else if (curPunc == "(") pushContext(state, stream.column(), ")");
179 else if (curPunc == "}") {
180 while (ctx.type == "statement") ctx = popContext(state);
181 if (ctx.type == "}") ctx = popContext(state);
182 while (ctx.type == "statement") ctx = popContext(state);
183 }
184 else if (curPunc == ctx.type) popContext(state);
185 else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
186 pushContext(state, stream.column(), "statement");
187 state.startOfLine = false;
188 return style;
189 },
190
191 indent: function(state, textAfter) {
192 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
193 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
194 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
195 var closing = firstChar == ctx.type;
196 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
197 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
198 else return ctx.indented + (closing ? 0 : indentUnit);
199 },
200
201 electricChars: "{}"
202 };
203 });
204
205 CodeMirror.defineMIME("text/x-ecl", "ecl");
206
207 });
@@ -1,162 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("eiffel", function() {
15 function wordObj(words) {
16 var o = {};
17 for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
18 return o;
19 }
20 var keywords = wordObj([
21 'note',
22 'across',
23 'when',
24 'variant',
25 'until',
26 'unique',
27 'undefine',
28 'then',
29 'strip',
30 'select',
31 'retry',
32 'rescue',
33 'require',
34 'rename',
35 'reference',
36 'redefine',
37 'prefix',
38 'once',
39 'old',
40 'obsolete',
41 'loop',
42 'local',
43 'like',
44 'is',
45 'inspect',
46 'infix',
47 'include',
48 'if',
49 'frozen',
50 'from',
51 'external',
52 'export',
53 'ensure',
54 'end',
55 'elseif',
56 'else',
57 'do',
58 'creation',
59 'create',
60 'check',
61 'alias',
62 'agent',
63 'separate',
64 'invariant',
65 'inherit',
66 'indexing',
67 'feature',
68 'expanded',
69 'deferred',
70 'class',
71 'Void',
72 'True',
73 'Result',
74 'Precursor',
75 'False',
76 'Current',
77 'create',
78 'attached',
79 'detachable',
80 'as',
81 'and',
82 'implies',
83 'not',
84 'or'
85 ]);
86 var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
87 var curPunc;
88
89 function chain(newtok, stream, state) {
90 state.tokenize.push(newtok);
91 return newtok(stream, state);
92 }
93
94 function tokenBase(stream, state) {
95 curPunc = null;
96 if (stream.eatSpace()) return null;
97 var ch = stream.next();
98 if (ch == '"'||ch == "'") {
99 return chain(readQuoted(ch, "string"), stream, state);
100 } else if (ch == "-"&&stream.eat("-")) {
101 stream.skipToEnd();
102 return "comment";
103 } else if (ch == ":"&&stream.eat("=")) {
104 return "operator";
105 } else if (/[0-9]/.test(ch)) {
106 stream.eatWhile(/[xXbBCc0-9\.]/);
107 stream.eat(/[\?\!]/);
108 return "ident";
109 } else if (/[a-zA-Z_0-9]/.test(ch)) {
110 stream.eatWhile(/[a-zA-Z_0-9]/);
111 stream.eat(/[\?\!]/);
112 return "ident";
113 } else if (/[=+\-\/*^%<>~]/.test(ch)) {
114 stream.eatWhile(/[=+\-\/*^%<>~]/);
115 return "operator";
116 } else {
117 return null;
118 }
119 }
120
121 function readQuoted(quote, style, unescaped) {
122 return function(stream, state) {
123 var escaped = false, ch;
124 while ((ch = stream.next()) != null) {
125 if (ch == quote && (unescaped || !escaped)) {
126 state.tokenize.pop();
127 break;
128 }
129 escaped = !escaped && ch == "%";
130 }
131 return style;
132 };
133 }
134
135 return {
136 startState: function() {
137 return {tokenize: [tokenBase]};
138 },
139
140 token: function(stream, state) {
141 var style = state.tokenize[state.tokenize.length-1](stream, state);
142 if (style == "ident") {
143 var word = stream.current();
144 style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
145 : operators.propertyIsEnumerable(stream.current()) ? "operator"
146 : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag"
147 : /^0[bB][0-1]+$/g.test(word) ? "number"
148 : /^0[cC][0-7]+$/g.test(word) ? "number"
149 : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number"
150 : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number"
151 : /^[0-9]+$/g.test(word) ? "number"
152 : "variable";
153 }
154 return style;
155 },
156 lineComment: "--"
157 };
158 });
159
160 CodeMirror.defineMIME("text/x-eiffel", "eiffel");
161
162 });
This diff has been collapsed as it changes many lines, (622 lines changed) Show them Hide them
@@ -1,622 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*jshint unused:true, eqnull:true, curly:true, bitwise:true */
5 /*jshint undef:true, latedef:true, trailing:true */
6 /*global CodeMirror:true */
7
8 // erlang mode.
9 // tokenizer -> token types -> CodeMirror styles
10 // tokenizer maintains a parse stack
11 // indenter uses the parse stack
12
13 // TODO indenter:
14 // bit syntax
15 // old guard/bif/conversion clashes (e.g. "float/1")
16 // type/spec/opaque
17
18 (function(mod) {
19 if (typeof exports == "object" && typeof module == "object") // CommonJS
20 mod(require("../../lib/codemirror"));
21 else if (typeof define == "function" && define.amd) // AMD
22 define(["../../lib/codemirror"], mod);
23 else // Plain browser env
24 mod(CodeMirror);
25 })(function(CodeMirror) {
26 "use strict";
27
28 CodeMirror.defineMIME("text/x-erlang", "erlang");
29
30 CodeMirror.defineMode("erlang", function(cmCfg) {
31 "use strict";
32
33 /////////////////////////////////////////////////////////////////////////////
34 // constants
35
36 var typeWords = [
37 "-type", "-spec", "-export_type", "-opaque"];
38
39 var keywordWords = [
40 "after","begin","catch","case","cond","end","fun","if",
41 "let","of","query","receive","try","when"];
42
43 var separatorRE = /[\->,;]/;
44 var separatorWords = [
45 "->",";",","];
46
47 var operatorAtomWords = [
48 "and","andalso","band","bnot","bor","bsl","bsr","bxor",
49 "div","not","or","orelse","rem","xor"];
50
51 var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
52 var operatorSymbolWords = [
53 "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
54
55 var openParenRE = /[<\(\[\{]/;
56 var openParenWords = [
57 "<<","(","[","{"];
58
59 var closeParenRE = /[>\)\]\}]/;
60 var closeParenWords = [
61 "}","]",")",">>"];
62
63 var guardWords = [
64 "is_atom","is_binary","is_bitstring","is_boolean","is_float",
65 "is_function","is_integer","is_list","is_number","is_pid",
66 "is_port","is_record","is_reference","is_tuple",
67 "atom","binary","bitstring","boolean","function","integer","list",
68 "number","pid","port","record","reference","tuple"];
69
70 var bifWords = [
71 "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
72 "atom_to_list","binary_to_atom","binary_to_existing_atom",
73 "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
74 "byte_size","check_process_code","contact_binary","crc32",
75 "crc32_combine","date","decode_packet","delete_module",
76 "disconnect_node","element","erase","exit","float","float_to_list",
77 "garbage_collect","get","get_keys","group_leader","halt","hd",
78 "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
79 "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
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",
82 "length","link","list_to_atom","list_to_binary","list_to_bitstring",
83 "list_to_existing_atom","list_to_float","list_to_integer",
84 "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
85 "monitor_node","node","node_link","node_unlink","nodes","notalive",
86 "now","open_port","pid_to_list","port_close","port_command",
87 "port_connect","port_control","pre_loaded","process_flag",
88 "process_info","processes","purge_module","put","register",
89 "registered","round","self","setelement","size","spawn","spawn_link",
90 "spawn_monitor","spawn_opt","split_binary","statistics",
91 "term_to_binary","time","throw","tl","trunc","tuple_size",
92 "tuple_to_list","unlink","unregister","whereis"];
93
94 // upper case: [A-Z] [Ø-Þ] [À-Ö]
95 // lower case: [a-z] [ß-ö] [ø-ÿ]
96 var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
97 var escapesRE =
98 /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
99
100 /////////////////////////////////////////////////////////////////////////////
101 // tokenizer
102
103 function tokenizer(stream,state) {
104 // in multi-line string
105 if (state.in_string) {
106 state.in_string = (!doubleQuote(stream));
107 return rval(state,stream,"string");
108 }
109
110 // in multi-line atom
111 if (state.in_atom) {
112 state.in_atom = (!singleQuote(stream));
113 return rval(state,stream,"atom");
114 }
115
116 // whitespace
117 if (stream.eatSpace()) {
118 return rval(state,stream,"whitespace");
119 }
120
121 // attributes and type specs
122 if (!peekToken(state) &&
123 stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
124 if (is_member(stream.current(),typeWords)) {
125 return rval(state,stream,"type");
126 }else{
127 return rval(state,stream,"attribute");
128 }
129 }
130
131 var ch = stream.next();
132
133 // comment
134 if (ch == '%') {
135 stream.skipToEnd();
136 return rval(state,stream,"comment");
137 }
138
139 // colon
140 if (ch == ":") {
141 return rval(state,stream,"colon");
142 }
143
144 // macro
145 if (ch == '?') {
146 stream.eatSpace();
147 stream.eatWhile(anumRE);
148 return rval(state,stream,"macro");
149 }
150
151 // record
152 if (ch == "#") {
153 stream.eatSpace();
154 stream.eatWhile(anumRE);
155 return rval(state,stream,"record");
156 }
157
158 // dollar escape
159 if (ch == "$") {
160 if (stream.next() == "\\" && !stream.match(escapesRE)) {
161 return rval(state,stream,"error");
162 }
163 return rval(state,stream,"number");
164 }
165
166 // dot
167 if (ch == ".") {
168 return rval(state,stream,"dot");
169 }
170
171 // quoted atom
172 if (ch == '\'') {
173 if (!(state.in_atom = (!singleQuote(stream)))) {
174 if (stream.match(/\s*\/\s*[0-9]/,false)) {
175 stream.match(/\s*\/\s*[0-9]/,true);
176 return rval(state,stream,"fun"); // 'f'/0 style fun
177 }
178 if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
179 return rval(state,stream,"function");
180 }
181 }
182 return rval(state,stream,"atom");
183 }
184
185 // string
186 if (ch == '"') {
187 state.in_string = (!doubleQuote(stream));
188 return rval(state,stream,"string");
189 }
190
191 // variable
192 if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
193 stream.eatWhile(anumRE);
194 return rval(state,stream,"variable");
195 }
196
197 // atom/keyword/BIF/function
198 if (/[a-z_ß-öø-ÿ]/.test(ch)) {
199 stream.eatWhile(anumRE);
200
201 if (stream.match(/\s*\/\s*[0-9]/,false)) {
202 stream.match(/\s*\/\s*[0-9]/,true);
203 return rval(state,stream,"fun"); // f/0 style fun
204 }
205
206 var w = stream.current();
207
208 if (is_member(w,keywordWords)) {
209 return rval(state,stream,"keyword");
210 }else if (is_member(w,operatorAtomWords)) {
211 return rval(state,stream,"operator");
212 }else if (stream.match(/\s*\(/,false)) {
213 // 'put' and 'erlang:put' are bifs, 'foo:put' is not
214 if (is_member(w,bifWords) &&
215 ((peekToken(state).token != ":") ||
216 (peekToken(state,2).token == "erlang"))) {
217 return rval(state,stream,"builtin");
218 }else if (is_member(w,guardWords)) {
219 return rval(state,stream,"guard");
220 }else{
221 return rval(state,stream,"function");
222 }
223 }else if (is_member(w,operatorAtomWords)) {
224 return rval(state,stream,"operator");
225 }else if (lookahead(stream) == ":") {
226 if (w == "erlang") {
227 return rval(state,stream,"builtin");
228 } else {
229 return rval(state,stream,"function");
230 }
231 }else if (is_member(w,["true","false"])) {
232 return rval(state,stream,"boolean");
233 }else if (is_member(w,["true","false"])) {
234 return rval(state,stream,"boolean");
235 }else{
236 return rval(state,stream,"atom");
237 }
238 }
239
240 // number
241 var digitRE = /[0-9]/;
242 var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
243 if (digitRE.test(ch)) {
244 stream.eatWhile(digitRE);
245 if (stream.eat('#')) { // 36#aZ style integer
246 if (!stream.eatWhile(radixRE)) {
247 stream.backUp(1); //"36#" - syntax error
248 }
249 } else if (stream.eat('.')) { // float
250 if (!stream.eatWhile(digitRE)) {
251 stream.backUp(1); // "3." - probably end of function
252 } else {
253 if (stream.eat(/[eE]/)) { // float with exponent
254 if (stream.eat(/[-+]/)) {
255 if (!stream.eatWhile(digitRE)) {
256 stream.backUp(2); // "2e-" - syntax error
257 }
258 } else {
259 if (!stream.eatWhile(digitRE)) {
260 stream.backUp(1); // "2e" - syntax error
261 }
262 }
263 }
264 }
265 }
266 return rval(state,stream,"number"); // normal integer
267 }
268
269 // open parens
270 if (nongreedy(stream,openParenRE,openParenWords)) {
271 return rval(state,stream,"open_paren");
272 }
273
274 // close parens
275 if (nongreedy(stream,closeParenRE,closeParenWords)) {
276 return rval(state,stream,"close_paren");
277 }
278
279 // separators
280 if (greedy(stream,separatorRE,separatorWords)) {
281 return rval(state,stream,"separator");
282 }
283
284 // operators
285 if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
286 return rval(state,stream,"operator");
287 }
288
289 return rval(state,stream,null);
290 }
291
292 /////////////////////////////////////////////////////////////////////////////
293 // utilities
294 function nongreedy(stream,re,words) {
295 if (stream.current().length == 1 && re.test(stream.current())) {
296 stream.backUp(1);
297 while (re.test(stream.peek())) {
298 stream.next();
299 if (is_member(stream.current(),words)) {
300 return true;
301 }
302 }
303 stream.backUp(stream.current().length-1);
304 }
305 return false;
306 }
307
308 function greedy(stream,re,words) {
309 if (stream.current().length == 1 && re.test(stream.current())) {
310 while (re.test(stream.peek())) {
311 stream.next();
312 }
313 while (0 < stream.current().length) {
314 if (is_member(stream.current(),words)) {
315 return true;
316 }else{
317 stream.backUp(1);
318 }
319 }
320 stream.next();
321 }
322 return false;
323 }
324
325 function doubleQuote(stream) {
326 return quote(stream, '"', '\\');
327 }
328
329 function singleQuote(stream) {
330 return quote(stream,'\'','\\');
331 }
332
333 function quote(stream,quoteChar,escapeChar) {
334 while (!stream.eol()) {
335 var ch = stream.next();
336 if (ch == quoteChar) {
337 return true;
338 }else if (ch == escapeChar) {
339 stream.next();
340 }
341 }
342 return false;
343 }
344
345 function lookahead(stream) {
346 var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
347 return m ? m.pop() : "";
348 }
349
350 function is_member(element,list) {
351 return (-1 < list.indexOf(element));
352 }
353
354 function rval(state,stream,type) {
355
356 // parse stack
357 pushToken(state,realToken(type,stream));
358
359 // map erlang token type to CodeMirror style class
360 // erlang -> CodeMirror tag
361 switch (type) {
362 case "atom": return "atom";
363 case "attribute": return "attribute";
364 case "boolean": return "atom";
365 case "builtin": return "builtin";
366 case "close_paren": return null;
367 case "colon": return null;
368 case "comment": return "comment";
369 case "dot": return null;
370 case "error": return "error";
371 case "fun": return "meta";
372 case "function": return "tag";
373 case "guard": return "property";
374 case "keyword": return "keyword";
375 case "macro": return "variable-2";
376 case "number": return "number";
377 case "open_paren": return null;
378 case "operator": return "operator";
379 case "record": return "bracket";
380 case "separator": return null;
381 case "string": return "string";
382 case "type": return "def";
383 case "variable": return "variable";
384 default: return null;
385 }
386 }
387
388 function aToken(tok,col,ind,typ) {
389 return {token: tok,
390 column: col,
391 indent: ind,
392 type: typ};
393 }
394
395 function realToken(type,stream) {
396 return aToken(stream.current(),
397 stream.column(),
398 stream.indentation(),
399 type);
400 }
401
402 function fakeToken(type) {
403 return aToken(type,0,0,type);
404 }
405
406 function peekToken(state,depth) {
407 var len = state.tokenStack.length;
408 var dep = (depth ? depth : 1);
409
410 if (len < dep) {
411 return false;
412 }else{
413 return state.tokenStack[len-dep];
414 }
415 }
416
417 function pushToken(state,token) {
418
419 if (!(token.type == "comment" || token.type == "whitespace")) {
420 state.tokenStack = maybe_drop_pre(state.tokenStack,token);
421 state.tokenStack = maybe_drop_post(state.tokenStack);
422 }
423 }
424
425 function maybe_drop_pre(s,token) {
426 var last = s.length-1;
427
428 if (0 < last && s[last].type === "record" && token.type === "dot") {
429 s.pop();
430 }else if (0 < last && s[last].type === "group") {
431 s.pop();
432 s.push(token);
433 }else{
434 s.push(token);
435 }
436 return s;
437 }
438
439 function maybe_drop_post(s) {
440 var last = s.length-1;
441
442 if (s[last].type === "dot") {
443 return [];
444 }
445 if (s[last].type === "fun" && s[last-1].token === "fun") {
446 return s.slice(0,last-1);
447 }
448 switch (s[s.length-1].token) {
449 case "}": return d(s,{g:["{"]});
450 case "]": return d(s,{i:["["]});
451 case ")": return d(s,{i:["("]});
452 case ">>": return d(s,{i:["<<"]});
453 case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
454 case ",": return d(s,{e:["begin","try","when","->",
455 ",","(","[","{","<<"]});
456 case "->": return d(s,{r:["when"],
457 m:["try","if","case","receive"]});
458 case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
459 case "catch":return d(s,{e:["try"]});
460 case "of": return d(s,{e:["case"]});
461 case "after":return d(s,{e:["receive","try"]});
462 default: return s;
463 }
464 }
465
466 function d(stack,tt) {
467 // stack is a stack of Token objects.
468 // tt is an object; {type:tokens}
469 // type is a char, tokens is a list of token strings.
470 // The function returns (possibly truncated) stack.
471 // 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
473 // 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.
475 // 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.
477 // 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.
479 // 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,
481 // in which case it will return an empty stack.
482
483 for (var type in tt) {
484 var len = stack.length-1;
485 var tokens = tt[type];
486 for (var i = len-1; -1 < i ; i--) {
487 if (is_member(stack[i].token,tokens)) {
488 var ss = stack.slice(0,i);
489 switch (type) {
490 case "m": return ss.concat(stack[i]).concat(stack[len]);
491 case "r": return ss.concat(stack[len]);
492 case "i": return ss;
493 case "g": return ss.concat(fakeToken("group"));
494 case "E": return ss.concat(stack[i]);
495 case "e": return ss.concat(stack[i]);
496 }
497 }
498 }
499 }
500 return (type == "E" ? [] : stack);
501 }
502
503 /////////////////////////////////////////////////////////////////////////////
504 // indenter
505
506 function indenter(state,textAfter) {
507 var t;
508 var unit = cmCfg.indentUnit;
509 var wordAfter = wordafter(textAfter);
510 var currT = peekToken(state,1);
511 var prevT = peekToken(state,2);
512
513 if (state.in_string || state.in_atom) {
514 return CodeMirror.Pass;
515 }else if (!prevT) {
516 return 0;
517 }else if (currT.token == "when") {
518 return currT.column+unit;
519 }else if (wordAfter === "when" && prevT.type === "function") {
520 return prevT.indent+unit;
521 }else if (wordAfter === "(" && currT.token === "fun") {
522 return currT.column+3;
523 }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
524 return t.column;
525 }else if (is_member(wordAfter,["end","after","of"])) {
526 t = getToken(state,["begin","case","fun","if","receive","try"]);
527 return t ? t.column : CodeMirror.Pass;
528 }else if (is_member(wordAfter,closeParenWords)) {
529 t = getToken(state,openParenWords);
530 return t ? t.column : CodeMirror.Pass;
531 }else if (is_member(currT.token,[",","|","||"]) ||
532 is_member(wordAfter,[",","|","||"])) {
533 t = postcommaToken(state);
534 return t ? t.column+t.token.length : unit;
535 }else if (currT.token == "->") {
536 if (is_member(prevT.token, ["receive","case","if","try"])) {
537 return prevT.column+unit+unit;
538 }else{
539 return prevT.column+unit;
540 }
541 }else if (is_member(currT.token,openParenWords)) {
542 return currT.column+currT.token.length;
543 }else{
544 t = defaultToken(state);
545 return truthy(t) ? t.column+unit : 0;
546 }
547 }
548
549 function wordafter(str) {
550 var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
551
552 return truthy(m) && (m.index === 0) ? m[0] : "";
553 }
554
555 function postcommaToken(state) {
556 var objs = state.tokenStack.slice(0,-1);
557 var i = getTokenIndex(objs,"type",["open_paren"]);
558
559 return truthy(objs[i]) ? objs[i] : false;
560 }
561
562 function defaultToken(state) {
563 var objs = state.tokenStack;
564 var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
565 var oper = getTokenIndex(objs,"type",["operator"]);
566
567 if (truthy(stop) && truthy(oper) && stop < oper) {
568 return objs[stop+1];
569 } else if (truthy(stop)) {
570 return objs[stop];
571 } else {
572 return false;
573 }
574 }
575
576 function getToken(state,tokens) {
577 var objs = state.tokenStack;
578 var i = getTokenIndex(objs,"token",tokens);
579
580 return truthy(objs[i]) ? objs[i] : false;
581 }
582
583 function getTokenIndex(objs,propname,propvals) {
584
585 for (var i = objs.length-1; -1 < i ; i--) {
586 if (is_member(objs[i][propname],propvals)) {
587 return i;
588 }
589 }
590 return false;
591 }
592
593 function truthy(x) {
594 return (x !== false) && (x != null);
595 }
596
597 /////////////////////////////////////////////////////////////////////////////
598 // this object defines the mode
599
600 return {
601 startState:
602 function() {
603 return {tokenStack: [],
604 in_string: false,
605 in_atom: false};
606 },
607
608 token:
609 function(stream, state) {
610 return tokenizer(stream, state);
611 },
612
613 indent:
614 function(state, textAfter) {
615 return indenter(state,textAfter);
616 },
617
618 lineComment: "%"
619 };
620 });
621
622 });
@@ -1,188 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("fortran", function() {
15 function words(array) {
16 var keys = {};
17 for (var i = 0; i < array.length; ++i) {
18 keys[array[i]] = true;
19 }
20 return keys;
21 }
22
23 var keywords = words([
24 "abstract", "accept", "allocatable", "allocate",
25 "array", "assign", "asynchronous", "backspace",
26 "bind", "block", "byte", "call", "case",
27 "class", "close", "common", "contains",
28 "continue", "cycle", "data", "deallocate",
29 "decode", "deferred", "dimension", "do",
30 "elemental", "else", "encode", "end",
31 "endif", "entry", "enumerator", "equivalence",
32 "exit", "external", "extrinsic", "final",
33 "forall", "format", "function", "generic",
34 "go", "goto", "if", "implicit", "import", "include",
35 "inquire", "intent", "interface", "intrinsic",
36 "module", "namelist", "non_intrinsic",
37 "non_overridable", "none", "nopass",
38 "nullify", "open", "optional", "options",
39 "parameter", "pass", "pause", "pointer",
40 "print", "private", "program", "protected",
41 "public", "pure", "read", "recursive", "result",
42 "return", "rewind", "save", "select", "sequence",
43 "stop", "subroutine", "target", "then", "to", "type",
44 "use", "value", "volatile", "where", "while",
45 "write"]);
46 var builtins = words(["abort", "abs", "access", "achar", "acos",
47 "adjustl", "adjustr", "aimag", "aint", "alarm",
48 "all", "allocated", "alog", "amax", "amin",
49 "amod", "and", "anint", "any", "asin",
50 "associated", "atan", "besj", "besjn", "besy",
51 "besyn", "bit_size", "btest", "cabs", "ccos",
52 "ceiling", "cexp", "char", "chdir", "chmod",
53 "clog", "cmplx", "command_argument_count",
54 "complex", "conjg", "cos", "cosh", "count",
55 "cpu_time", "cshift", "csin", "csqrt", "ctime",
56 "c_funloc", "c_loc", "c_associated", "c_null_ptr",
57 "c_null_funptr", "c_f_pointer", "c_null_char",
58 "c_alert", "c_backspace", "c_form_feed",
59 "c_new_line", "c_carriage_return",
60 "c_horizontal_tab", "c_vertical_tab", "dabs",
61 "dacos", "dasin", "datan", "date_and_time",
62 "dbesj", "dbesj", "dbesjn", "dbesy", "dbesy",
63 "dbesyn", "dble", "dcos", "dcosh", "ddim", "derf",
64 "derfc", "dexp", "digits", "dim", "dint", "dlog",
65 "dlog", "dmax", "dmin", "dmod", "dnint",
66 "dot_product", "dprod", "dsign", "dsinh",
67 "dsin", "dsqrt", "dtanh", "dtan", "dtime",
68 "eoshift", "epsilon", "erf", "erfc", "etime",
69 "exit", "exp", "exponent", "extends_type_of",
70 "fdate", "fget", "fgetc", "float", "floor",
71 "flush", "fnum", "fputc", "fput", "fraction",
72 "fseek", "fstat", "ftell", "gerror", "getarg",
73 "get_command", "get_command_argument",
74 "get_environment_variable", "getcwd",
75 "getenv", "getgid", "getlog", "getpid",
76 "getuid", "gmtime", "hostnm", "huge", "iabs",
77 "iachar", "iand", "iargc", "ibclr", "ibits",
78 "ibset", "ichar", "idate", "idim", "idint",
79 "idnint", "ieor", "ierrno", "ifix", "imag",
80 "imagpart", "index", "int", "ior", "irand",
81 "isatty", "ishft", "ishftc", "isign",
82 "iso_c_binding", "is_iostat_end", "is_iostat_eor",
83 "itime", "kill", "kind", "lbound", "len", "len_trim",
84 "lge", "lgt", "link", "lle", "llt", "lnblnk", "loc",
85 "log", "logical", "long", "lshift", "lstat", "ltime",
86 "matmul", "max", "maxexponent", "maxloc", "maxval",
87 "mclock", "merge", "move_alloc", "min", "minexponent",
88 "minloc", "minval", "mod", "modulo", "mvbits",
89 "nearest", "new_line", "nint", "not", "or", "pack",
90 "perror", "precision", "present", "product", "radix",
91 "rand", "random_number", "random_seed", "range",
92 "real", "realpart", "rename", "repeat", "reshape",
93 "rrspacing", "rshift", "same_type_as", "scale",
94 "scan", "second", "selected_int_kind",
95 "selected_real_kind", "set_exponent", "shape",
96 "short", "sign", "signal", "sinh", "sin", "sleep",
97 "sngl", "spacing", "spread", "sqrt", "srand", "stat",
98 "sum", "symlnk", "system", "system_clock", "tan",
99 "tanh", "time", "tiny", "transfer", "transpose",
100 "trim", "ttynam", "ubound", "umask", "unlink",
101 "unpack", "verify", "xor", "zabs", "zcos", "zexp",
102 "zlog", "zsin", "zsqrt"]);
103
104 var dataTypes = words(["c_bool", "c_char", "c_double", "c_double_complex",
105 "c_float", "c_float_complex", "c_funptr", "c_int",
106 "c_int16_t", "c_int32_t", "c_int64_t", "c_int8_t",
107 "c_int_fast16_t", "c_int_fast32_t", "c_int_fast64_t",
108 "c_int_fast8_t", "c_int_least16_t", "c_int_least32_t",
109 "c_int_least64_t", "c_int_least8_t", "c_intmax_t",
110 "c_intptr_t", "c_long", "c_long_double",
111 "c_long_double_complex", "c_long_long", "c_ptr",
112 "c_short", "c_signed_char", "c_size_t", "character",
113 "complex", "double", "integer", "logical", "real"]);
114 var isOperatorChar = /[+\-*&=<>\/\:]/;
115 var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i");
116
117 function tokenBase(stream, state) {
118
119 if (stream.match(litOperator)){
120 return 'operator';
121 }
122
123 var ch = stream.next();
124 if (ch == "!") {
125 stream.skipToEnd();
126 return "comment";
127 }
128 if (ch == '"' || ch == "'") {
129 state.tokenize = tokenString(ch);
130 return state.tokenize(stream, state);
131 }
132 if (/[\[\]\(\),]/.test(ch)) {
133 return null;
134 }
135 if (/\d/.test(ch)) {
136 stream.eatWhile(/[\w\.]/);
137 return "number";
138 }
139 if (isOperatorChar.test(ch)) {
140 stream.eatWhile(isOperatorChar);
141 return "operator";
142 }
143 stream.eatWhile(/[\w\$_]/);
144 var word = stream.current().toLowerCase();
145
146 if (keywords.hasOwnProperty(word)){
147 return 'keyword';
148 }
149 if (builtins.hasOwnProperty(word) || dataTypes.hasOwnProperty(word)) {
150 return 'builtin';
151 }
152 return "variable";
153 }
154
155 function tokenString(quote) {
156 return function(stream, state) {
157 var escaped = false, next, end = false;
158 while ((next = stream.next()) != null) {
159 if (next == quote && !escaped) {
160 end = true;
161 break;
162 }
163 escaped = !escaped && next == "\\";
164 }
165 if (end || !escaped) state.tokenize = null;
166 return "string";
167 };
168 }
169
170 // Interface
171
172 return {
173 startState: function() {
174 return {tokenize: null};
175 },
176
177 token: function(stream, state) {
178 if (stream.eatSpace()) return null;
179 var style = (state.tokenize || tokenBase)(stream, state);
180 if (style == "comment" || style == "meta") return style;
181 return style;
182 }
183 };
184 });
185
186 CodeMirror.defineMIME("text/x-fortran", "fortran");
187
188 });
@@ -1,345 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("gas", function(_config, parserConfig) {
15 'use strict';
16
17 // If an architecture is specified, its initialization function may
18 // populate this array with custom parsing functions which will be
19 // tried in the event that the standard functions do not find a match.
20 var custom = [];
21
22 // The symbol used to start a line comment changes based on the target
23 // architecture.
24 // If no architecture is pased in "parserConfig" then only multiline
25 // comments will have syntax support.
26 var lineCommentStartSymbol = "";
27
28 // These directives are architecture independent.
29 // Machine specific directives should go in their respective
30 // architecture initialization function.
31 // Reference:
32 // http://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops
33 var directives = {
34 ".abort" : "builtin",
35 ".align" : "builtin",
36 ".altmacro" : "builtin",
37 ".ascii" : "builtin",
38 ".asciz" : "builtin",
39 ".balign" : "builtin",
40 ".balignw" : "builtin",
41 ".balignl" : "builtin",
42 ".bundle_align_mode" : "builtin",
43 ".bundle_lock" : "builtin",
44 ".bundle_unlock" : "builtin",
45 ".byte" : "builtin",
46 ".cfi_startproc" : "builtin",
47 ".comm" : "builtin",
48 ".data" : "builtin",
49 ".def" : "builtin",
50 ".desc" : "builtin",
51 ".dim" : "builtin",
52 ".double" : "builtin",
53 ".eject" : "builtin",
54 ".else" : "builtin",
55 ".elseif" : "builtin",
56 ".end" : "builtin",
57 ".endef" : "builtin",
58 ".endfunc" : "builtin",
59 ".endif" : "builtin",
60 ".equ" : "builtin",
61 ".equiv" : "builtin",
62 ".eqv" : "builtin",
63 ".err" : "builtin",
64 ".error" : "builtin",
65 ".exitm" : "builtin",
66 ".extern" : "builtin",
67 ".fail" : "builtin",
68 ".file" : "builtin",
69 ".fill" : "builtin",
70 ".float" : "builtin",
71 ".func" : "builtin",
72 ".global" : "builtin",
73 ".gnu_attribute" : "builtin",
74 ".hidden" : "builtin",
75 ".hword" : "builtin",
76 ".ident" : "builtin",
77 ".if" : "builtin",
78 ".incbin" : "builtin",
79 ".include" : "builtin",
80 ".int" : "builtin",
81 ".internal" : "builtin",
82 ".irp" : "builtin",
83 ".irpc" : "builtin",
84 ".lcomm" : "builtin",
85 ".lflags" : "builtin",
86 ".line" : "builtin",
87 ".linkonce" : "builtin",
88 ".list" : "builtin",
89 ".ln" : "builtin",
90 ".loc" : "builtin",
91 ".loc_mark_labels" : "builtin",
92 ".local" : "builtin",
93 ".long" : "builtin",
94 ".macro" : "builtin",
95 ".mri" : "builtin",
96 ".noaltmacro" : "builtin",
97 ".nolist" : "builtin",
98 ".octa" : "builtin",
99 ".offset" : "builtin",
100 ".org" : "builtin",
101 ".p2align" : "builtin",
102 ".popsection" : "builtin",
103 ".previous" : "builtin",
104 ".print" : "builtin",
105 ".protected" : "builtin",
106 ".psize" : "builtin",
107 ".purgem" : "builtin",
108 ".pushsection" : "builtin",
109 ".quad" : "builtin",
110 ".reloc" : "builtin",
111 ".rept" : "builtin",
112 ".sbttl" : "builtin",
113 ".scl" : "builtin",
114 ".section" : "builtin",
115 ".set" : "builtin",
116 ".short" : "builtin",
117 ".single" : "builtin",
118 ".size" : "builtin",
119 ".skip" : "builtin",
120 ".sleb128" : "builtin",
121 ".space" : "builtin",
122 ".stab" : "builtin",
123 ".string" : "builtin",
124 ".struct" : "builtin",
125 ".subsection" : "builtin",
126 ".symver" : "builtin",
127 ".tag" : "builtin",
128 ".text" : "builtin",
129 ".title" : "builtin",
130 ".type" : "builtin",
131 ".uleb128" : "builtin",
132 ".val" : "builtin",
133 ".version" : "builtin",
134 ".vtable_entry" : "builtin",
135 ".vtable_inherit" : "builtin",
136 ".warning" : "builtin",
137 ".weak" : "builtin",
138 ".weakref" : "builtin",
139 ".word" : "builtin"
140 };
141
142 var registers = {};
143
144 function x86(_parserConfig) {
145 lineCommentStartSymbol = "#";
146
147 registers.ax = "variable";
148 registers.eax = "variable-2";
149 registers.rax = "variable-3";
150
151 registers.bx = "variable";
152 registers.ebx = "variable-2";
153 registers.rbx = "variable-3";
154
155 registers.cx = "variable";
156 registers.ecx = "variable-2";
157 registers.rcx = "variable-3";
158
159 registers.dx = "variable";
160 registers.edx = "variable-2";
161 registers.rdx = "variable-3";
162
163 registers.si = "variable";
164 registers.esi = "variable-2";
165 registers.rsi = "variable-3";
166
167 registers.di = "variable";
168 registers.edi = "variable-2";
169 registers.rdi = "variable-3";
170
171 registers.sp = "variable";
172 registers.esp = "variable-2";
173 registers.rsp = "variable-3";
174
175 registers.bp = "variable";
176 registers.ebp = "variable-2";
177 registers.rbp = "variable-3";
178
179 registers.ip = "variable";
180 registers.eip = "variable-2";
181 registers.rip = "variable-3";
182
183 registers.cs = "keyword";
184 registers.ds = "keyword";
185 registers.ss = "keyword";
186 registers.es = "keyword";
187 registers.fs = "keyword";
188 registers.gs = "keyword";
189 }
190
191 function armv6(_parserConfig) {
192 // Reference:
193 // http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf
194 // http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301h/DDI0301H_arm1176jzfs_r0p7_trm.pdf
195 lineCommentStartSymbol = "@";
196 directives.syntax = "builtin";
197
198 registers.r0 = "variable";
199 registers.r1 = "variable";
200 registers.r2 = "variable";
201 registers.r3 = "variable";
202 registers.r4 = "variable";
203 registers.r5 = "variable";
204 registers.r6 = "variable";
205 registers.r7 = "variable";
206 registers.r8 = "variable";
207 registers.r9 = "variable";
208 registers.r10 = "variable";
209 registers.r11 = "variable";
210 registers.r12 = "variable";
211
212 registers.sp = "variable-2";
213 registers.lr = "variable-2";
214 registers.pc = "variable-2";
215 registers.r13 = registers.sp;
216 registers.r14 = registers.lr;
217 registers.r15 = registers.pc;
218
219 custom.push(function(ch, stream) {
220 if (ch === '#') {
221 stream.eatWhile(/\w/);
222 return "number";
223 }
224 });
225 }
226
227 var arch = (parserConfig.architecture || "x86").toLowerCase();
228 if (arch === "x86") {
229 x86(parserConfig);
230 } else if (arch === "arm" || arch === "armv6") {
231 armv6(parserConfig);
232 }
233
234 function nextUntilUnescaped(stream, end) {
235 var escaped = false, next;
236 while ((next = stream.next()) != null) {
237 if (next === end && !escaped) {
238 return false;
239 }
240 escaped = !escaped && next === "\\";
241 }
242 return escaped;
243 }
244
245 function clikeComment(stream, state) {
246 var maybeEnd = false, ch;
247 while ((ch = stream.next()) != null) {
248 if (ch === "/" && maybeEnd) {
249 state.tokenize = null;
250 break;
251 }
252 maybeEnd = (ch === "*");
253 }
254 return "comment";
255 }
256
257 return {
258 startState: function() {
259 return {
260 tokenize: null
261 };
262 },
263
264 token: function(stream, state) {
265 if (state.tokenize) {
266 return state.tokenize(stream, state);
267 }
268
269 if (stream.eatSpace()) {
270 return null;
271 }
272
273 var style, cur, ch = stream.next();
274
275 if (ch === "/") {
276 if (stream.eat("*")) {
277 state.tokenize = clikeComment;
278 return clikeComment(stream, state);
279 }
280 }
281
282 if (ch === lineCommentStartSymbol) {
283 stream.skipToEnd();
284 return "comment";
285 }
286
287 if (ch === '"') {
288 nextUntilUnescaped(stream, '"');
289 return "string";
290 }
291
292 if (ch === '.') {
293 stream.eatWhile(/\w/);
294 cur = stream.current().toLowerCase();
295 style = directives[cur];
296 return style || null;
297 }
298
299 if (ch === '=') {
300 stream.eatWhile(/\w/);
301 return "tag";
302 }
303
304 if (ch === '{') {
305 return "braket";
306 }
307
308 if (ch === '}') {
309 return "braket";
310 }
311
312 if (/\d/.test(ch)) {
313 if (ch === "0" && stream.eat("x")) {
314 stream.eatWhile(/[0-9a-fA-F]/);
315 return "number";
316 }
317 stream.eatWhile(/\d/);
318 return "number";
319 }
320
321 if (/\w/.test(ch)) {
322 stream.eatWhile(/\w/);
323 if (stream.eat(":")) {
324 return 'tag';
325 }
326 cur = stream.current().toLowerCase();
327 style = registers[cur];
328 return style || null;
329 }
330
331 for (var i = 0; i < custom.length; i++) {
332 style = custom[i](ch, stream, state);
333 if (style) {
334 return style;
335 }
336 }
337 },
338
339 lineComment: lineCommentStartSymbol,
340 blockCommentStart: "/*",
341 blockCommentEnd: "*/"
342 };
343 });
344
345 });
@@ -1,122 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("gfm", function(config, modeConfig) {
15 var codeDepth = 0;
16 function blankLine(state) {
17 state.code = false;
18 return null;
19 }
20 var gfmOverlay = {
21 startState: function() {
22 return {
23 code: false,
24 codeBlock: false,
25 ateSpace: false
26 };
27 },
28 copyState: function(s) {
29 return {
30 code: s.code,
31 codeBlock: s.codeBlock,
32 ateSpace: s.ateSpace
33 };
34 },
35 token: function(stream, state) {
36 state.combineTokens = null;
37
38 // Hack to prevent formatting override inside code blocks (block and inline)
39 if (state.codeBlock) {
40 if (stream.match(/^```/)) {
41 state.codeBlock = false;
42 return null;
43 }
44 stream.skipToEnd();
45 return null;
46 }
47 if (stream.sol()) {
48 state.code = false;
49 }
50 if (stream.sol() && stream.match(/^```/)) {
51 stream.skipToEnd();
52 state.codeBlock = true;
53 return null;
54 }
55 // If this block is changed, it may need to be updated in Markdown mode
56 if (stream.peek() === '`') {
57 stream.next();
58 var before = stream.pos;
59 stream.eatWhile('`');
60 var difference = 1 + stream.pos - before;
61 if (!state.code) {
62 codeDepth = difference;
63 state.code = true;
64 } else {
65 if (difference === codeDepth) { // Must be exact
66 state.code = false;
67 }
68 }
69 return null;
70 } else if (state.code) {
71 stream.next();
72 return null;
73 }
74 // Check if space. If so, links can be formatted later on
75 if (stream.eatSpace()) {
76 state.ateSpace = true;
77 return null;
78 }
79 if (stream.sol() || state.ateSpace) {
80 state.ateSpace = false;
81 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
82 // User/Project@SHA
83 // User@SHA
84 // SHA
85 state.combineTokens = true;
86 return "link";
87 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
88 // User/Project#Num
89 // User#Num
90 // #Num
91 state.combineTokens = true;
92 return "link";
93 }
94 }
95 if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
96 stream.string.slice(stream.start - 2, stream.start) != "](") {
97 // URLs
98 // 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
100 state.combineTokens = true;
101 return "link";
102 }
103 stream.next();
104 return null;
105 },
106 blankLine: blankLine
107 };
108
109 var markdownConfig = {
110 underscoresBreakWords: false,
111 taskLists: true,
112 fencedCodeBlocks: true
113 };
114 for (var attr in modeConfig) {
115 markdownConfig[attr] = modeConfig[attr];
116 }
117 markdownConfig.name = "markdown";
118 CodeMirror.defineMIME("gfmBase", markdownConfig);
119 return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
120 }, "markdown");
121
122 });
@@ -1,178 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 Gherkin mode - http://www.cukes.info/
6 Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
7 */
8
9 // Following Objs from Brackets implementation: https://github.com/tregusti/brackets-gherkin/blob/master/main.js
10 //var Quotes = {
11 // SINGLE: 1,
12 // DOUBLE: 2
13 //};
14
15 //var regex = {
16 // keywords: /(Feature| {2}(Scenario|In order to|As|I)| {4}(Given|When|Then|And))/
17 //};
18
19 (function(mod) {
20 if (typeof exports == "object" && typeof module == "object") // CommonJS
21 mod(require("../../lib/codemirror"));
22 else if (typeof define == "function" && define.amd) // AMD
23 define(["../../lib/codemirror"], mod);
24 else // Plain browser env
25 mod(CodeMirror);
26 })(function(CodeMirror) {
27 "use strict";
28
29 CodeMirror.defineMode("gherkin", function () {
30 return {
31 startState: function () {
32 return {
33 lineNumber: 0,
34 tableHeaderLine: false,
35 allowFeature: true,
36 allowBackground: false,
37 allowScenario: false,
38 allowSteps: false,
39 allowPlaceholders: false,
40 allowMultilineArgument: false,
41 inMultilineString: false,
42 inMultilineTable: false,
43 inKeywordLine: false
44 };
45 },
46 token: function (stream, state) {
47 if (stream.sol()) {
48 state.lineNumber++;
49 state.inKeywordLine = false;
50 if (state.inMultilineTable) {
51 state.tableHeaderLine = false;
52 if (!stream.match(/\s*\|/, false)) {
53 state.allowMultilineArgument = false;
54 state.inMultilineTable = false;
55 }
56 }
57 }
58
59 stream.eatSpace();
60
61 if (state.allowMultilineArgument) {
62
63 // STRING
64 if (state.inMultilineString) {
65 if (stream.match('"""')) {
66 state.inMultilineString = false;
67 state.allowMultilineArgument = false;
68 } else {
69 stream.match(/.*/);
70 }
71 return "string";
72 }
73
74 // TABLE
75 if (state.inMultilineTable) {
76 if (stream.match(/\|\s*/)) {
77 return "bracket";
78 } else {
79 stream.match(/[^\|]*/);
80 return state.tableHeaderLine ? "header" : "string";
81 }
82 }
83
84 // DETECT START
85 if (stream.match('"""')) {
86 // String
87 state.inMultilineString = true;
88 return "string";
89 } else if (stream.match("|")) {
90 // Table
91 state.inMultilineTable = true;
92 state.tableHeaderLine = true;
93 return "bracket";
94 }
95
96 }
97
98 // LINE COMMENT
99 if (stream.match(/#.*/)) {
100 return "comment";
101
102 // TAG
103 } else if (!state.inKeywordLine && stream.match(/@\S+/)) {
104 return "tag";
105
106 // FEATURE
107 } else if (!state.inKeywordLine && state.allowFeature && stream.match(/(機能|功能|フィーチャ|기능|โครงหลัก|ความสามารถ|ความต้องการทางธุรกิจ|ಹೆಚ್ಚಳ|గుణము|ਮੁਹਾਂਦਰਾ|ਨਕਸ਼ ਨੁਹਾਰ|ਖਾਸੀਅਤ|रूप लेख|وِیژگی|خاصية|תכונה|Функціонал|Функция|Функционалност|Функционал|Үзенчәлеклелек|Свойство|Особина|Мөмкинлек|Могућност|Λειτουργία|Δυνατότητα|Właściwość|Vlastnosť|Trajto|Tính năng|Savybė|Pretty much|Požiadavka|Požadavek|Potrzeba biznesowa|Özellik|Osobina|Ominaisuus|Omadus|OH HAI|Mogućnost|Mogucnost|Jellemző|Hwæt|Hwaet|Funzionalità|Funktionalitéit|Funktionalität|Funkcja|Funkcionalnost|Funkcionalitāte|Funkcia|Fungsi|Functionaliteit|Funcționalitate|Funcţionalitate|Functionalitate|Funcionalitat|Funcionalidade|Fonctionnalité|Fitur|Fīča|Feature|Eiginleiki|Egenskap|Egenskab|Característica|Caracteristica|Business Need|Aspekt|Arwedd|Ahoy matey!|Ability):/)) {
108 state.allowScenario = true;
109 state.allowBackground = true;
110 state.allowPlaceholders = false;
111 state.allowSteps = false;
112 state.allowMultilineArgument = false;
113 state.inKeywordLine = true;
114 return "keyword";
115
116 // BACKGROUND
117 } else if (!state.inKeywordLine && state.allowBackground && stream.match(/(背景|배경|แนวคิด|ಹಿನ್ನೆಲೆ|నేపథ్యం|ਪਿਛੋਕੜ|पृष्ठभूमि|زمینه|الخلفية|רקע|Тарих|Предыстория|Предистория|Позадина|Передумова|Основа|Контекст|Кереш|Υπόβαθρο|Założenia|Yo\-ho\-ho|Tausta|Taust|Situācija|Rerefons|Pozadina|Pozadie|Pozadí|Osnova|Latar Belakang|Kontext|Konteksts|Kontekstas|Kontekst|Háttér|Hannergrond|Grundlage|Geçmiş|Fundo|Fono|First off|Dis is what went down|Dasar|Contexto|Contexte|Context|Contesto|Cenário de Fundo|Cenario de Fundo|Cefndir|Bối cảnh|Bakgrunnur|Bakgrunn|Bakgrund|Baggrund|Background|B4|Antecedents|Antecedentes|Ær|Aer|Achtergrond):/)) {
118 state.allowPlaceholders = false;
119 state.allowSteps = true;
120 state.allowBackground = false;
121 state.allowMultilineArgument = false;
122 state.inKeywordLine = true;
123 return "keyword";
124
125 // SCENARIO OUTLINE
126 } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景大綱|场景大纲|劇本大綱|剧本大纲|テンプレ|シナリオテンプレート|シナリオテンプレ|シナリオアウトライン|시나리오 개요|สรุปเหตุการณ์|โครงสร้างของเหตุการณ์|ವಿವರಣೆ|కథనం|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਟਕਥਾ ਢਾਂਚਾ|परिदृश्य रूपरेखा|سيناريو مخطط|الگوی سناریو|תבנית תרחיש|Сценарийның төзелеше|Сценарий структураси|Структура сценарію|Структура сценария|Структура сценарија|Скица|Рамка на сценарий|Концепт|Περιγραφή Σεναρίου|Wharrimean is|Template Situai|Template Senario|Template Keadaan|Tapausaihio|Szenariogrundriss|Szablon scenariusza|Swa hwær swa|Swa hwaer swa|Struktura scenarija|Structură scenariu|Structura scenariu|Skica|Skenario konsep|Shiver me timbers|Senaryo taslağı|Schema dello scenario|Scenariomall|Scenariomal|Scenario Template|Scenario Outline|Scenario Amlinellol|Scenārijs pēc parauga|Scenarijaus šablonas|Reckon it's like|Raamstsenaarium|Plang vum Szenario|Plan du Scénario|Plan du scénario|Osnova scénáře|Osnova Scenára|Náčrt Scenáru|Náčrt Scénáře|Náčrt Scenára|MISHUN SRSLY|Menggariskan Senario|Lýsing Dæma|Lýsing Atburðarásar|Konturo de la scenaro|Koncept|Khung tình huống|Khung kịch bản|Forgatókönyv vázlat|Esquema do Cenário|Esquema do Cenario|Esquema del escenario|Esquema de l'escenari|Esbozo do escenario|Delineação do Cenário|Delineacao do Cenario|All y'all|Abstrakt Scenario|Abstract Scenario):/)) {
127 state.allowPlaceholders = true;
128 state.allowSteps = true;
129 state.allowMultilineArgument = false;
130 state.inKeywordLine = true;
131 return "keyword";
132
133 // EXAMPLES
134 } else if (state.allowScenario && stream.match(/(例子|例|サンプル|예|ชุดของเหตุการณ์|ชุดของตัวอย่าง|ಉದಾಹರಣೆಗಳು|ఉదాహరణలు|ਉਦਾਹਰਨਾਂ|उदाहरण|نمونه ها|امثلة|דוגמאות|Үрнәкләр|Сценарији|Примеры|Примери|Приклади|Мисоллар|Мисаллар|Σενάρια|Παραδείγματα|You'll wanna|Voorbeelden|Variantai|Tapaukset|Se þe|Se the|Se ðe|Scenarios|Scenariji|Scenarijai|Przykłady|Primjeri|Primeri|Příklady|Príklady|Piemēri|Példák|Pavyzdžiai|Paraugs|Örnekler|Juhtumid|Exemplos|Exemples|Exemple|Exempel|EXAMPLZ|Examples|Esempi|Enghreifftiau|Ekzemploj|Eksempler|Ejemplos|Dữ liệu|Dead men tell no tales|Dæmi|Contoh|Cenários|Cenarios|Beispiller|Beispiele|Atburðarásir):/)) {
135 state.allowPlaceholders = false;
136 state.allowSteps = true;
137 state.allowBackground = false;
138 state.allowMultilineArgument = true;
139 return "keyword";
140
141 // SCENARIO
142 } else if (!state.inKeywordLine && state.allowScenario && stream.match(/(場景|场景|劇本|剧本|シナリオ|시나리오|เหตุการณ์|ಕಥಾಸಾರಾಂಶ|సన్నివేశం|ਪਟਕਥਾ|परिदृश्य|سيناريو|سناریو|תרחיש|Сценарій|Сценарио|Сценарий|Пример|Σενάριο|Tình huống|The thing of it is|Tapaus|Szenario|Swa|Stsenaarium|Skenario|Situai|Senaryo|Senario|Scenaro|Scenariusz|Scenariu|Scénario|Scenario|Scenarijus|Scenārijs|Scenarij|Scenarie|Scénář|Scenár|Primer|MISHUN|Kịch bản|Keadaan|Heave to|Forgatókönyv|Escenario|Escenari|Cenário|Cenario|Awww, look mate|Atburðarás):/)) {
143 state.allowPlaceholders = false;
144 state.allowSteps = true;
145 state.allowBackground = false;
146 state.allowMultilineArgument = false;
147 state.inKeywordLine = true;
148 return "keyword";
149
150 // STEPS
151 } else if (!state.inKeywordLine && state.allowSteps && stream.match(/(那麼|那么|而且|當|当|并且|同時|同时|前提|假设|假設|假定|假如|但是|但し|並且|もし|ならば|ただし|しかし|かつ|하지만|조건|먼저|만일|만약|단|그리고|그러면|และ |เมื่อ |แต่ |ดังนั้น |กำหนดให้ |ಸ್ಥಿತಿಯನ್ನು |ಮತ್ತು |ನೀಡಿದ |ನಂತರ |ಆದರೆ |మరియు |చెప్పబడినది |కాని |ఈ పరిస్థితిలో |అప్పుడు |ਪਰ |ਤਦ |ਜੇਕਰ |ਜਿਵੇਂ ਕਿ |ਜਦੋਂ |ਅਤੇ |यदि |परन्तु |पर |तब |तदा |तथा |जब |चूंकि |किन्तु |कदा |और |अगर |و |هنگامی |متى |لكن |عندما |ثم |بفرض |با فرض |اما |اذاً |آنگاه |כאשר |וגם |בהינתן |אזי |אז |אבל |Якщо |Һәм |Унда |Тоді |Тогда |То |Также |Та |Пусть |Припустимо, що |Припустимо |Онда |Но |Нехай |Нәтиҗәдә |Лекин |Ләкин |Коли |Когда |Когато |Када |Кад |К тому же |І |И |Задато |Задати |Задате |Если |Допустим |Дано |Дадено |Вә |Ва |Бирок |Әмма |Әйтик |Әгәр |Аммо |Али |Але |Агар |А також |А |Τότε |Όταν |Και |Δεδομένου |Αλλά |Þurh |Þegar |Þa þe |Þá |Þa |Zatati |Zakładając |Zadato |Zadate |Zadano |Zadani |Zadan |Za předpokladu |Za predpokladu |Youse know when youse got |Youse know like when |Yna |Yeah nah |Y'know |Y |Wun |Wtedy |When y'all |When |Wenn |WEN |wann |Ve |Và |Und |Un |ugeholl |Too right |Thurh |Thì |Then y'all |Then |Tha the |Tha |Tetapi |Tapi |Tak |Tada |Tad |Stel |Soit |Siis |Și |Şi |Si |Sed |Se |Så |Quando |Quand |Quan |Pryd |Potom |Pokud |Pokiaľ |Però |Pero |Pak |Oraz |Onda |Ond |Oletetaan |Og |Och |O zaman |Niin |Nhưng |När |Når |Mutta |Men |Mas |Maka |Majd |Mając |Mais |Maar |mä |Ma |Lorsque |Lorsqu'|Logo |Let go and haul |Kun |Kuid |Kui |Kiedy |Khi |Ketika |Kemudian |Keď |Když |Kaj |Kai |Kada |Kad |Jeżeli |Jeśli |Ja |It's just unbelievable |Ir |I CAN HAZ |I |Ha |Givun |Givet |Given y'all |Given |Gitt |Gegeven |Gegeben seien |Gegeben sei |Gdy |Gangway! |Fakat |Étant donnés |Etant donnés |Étant données |Etant données |Étant donnée |Etant donnée |Étant donné |Etant donné |Et |És |Entonces |Entón |Então |Entao |En |Eğer ki |Ef |Eeldades |E |Ðurh |Duota |Dun |Donitaĵo |Donat |Donada |Do |Diyelim ki |Diberi |Dengan |Den youse gotta |DEN |De |Dato |Dați fiind |Daţi fiind |Dati fiind |Dati |Date fiind |Date |Data |Dat fiind |Dar |Dann |dann |Dan |Dados |Dado |Dadas |Dada |Ða ðe |Ða |Cuando |Cho |Cando |Când |Cand |Cal |But y'all |But at the end of the day I reckon |BUT |But |Buh |Blimey! |Biết |Bet |Bagi |Aye |awer |Avast! |Atunci |Atesa |Atès |Apabila |Anrhegedig a |Angenommen |And y'all |And |AN |An |an |Amikor |Amennyiben |Ama |Als |Alors |Allora |Ali |Aleshores |Ale |Akkor |Ak |Adott |Ac |Aber |A zároveň |A tiež |A taktiež |A také |A |a |7 |\* )/)) {
152 state.inStep = true;
153 state.allowPlaceholders = true;
154 state.allowMultilineArgument = true;
155 state.inKeywordLine = true;
156 return "keyword";
157
158 // INLINE STRING
159 } else if (stream.match(/"[^"]*"?/)) {
160 return "string";
161
162 // PLACEHOLDER
163 } else if (state.allowPlaceholders && stream.match(/<[^>]*>?/)) {
164 return "variable";
165
166 // Fall through
167 } else {
168 stream.next();
169 stream.eatWhile(/[^@"<#]/);
170 return null;
171 }
172 }
173 };
174 });
175
176 CodeMirror.defineMIME("text/x-feature", "gherkin");
177
178 });
@@ -1,184 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("go", function(config) {
15 var indentUnit = config.indentUnit;
16
17 var keywords = {
18 "break":true, "case":true, "chan":true, "const":true, "continue":true,
19 "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
20 "func":true, "go":true, "goto":true, "if":true, "import":true,
21 "interface":true, "map":true, "package":true, "range":true, "return":true,
22 "select":true, "struct":true, "switch":true, "type":true, "var":true,
23 "bool":true, "byte":true, "complex64":true, "complex128":true,
24 "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
25 "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
26 "uint64":true, "int":true, "uint":true, "uintptr":true
27 };
28
29 var atoms = {
30 "true":true, "false":true, "iota":true, "nil":true, "append":true,
31 "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
32 "len":true, "make":true, "new":true, "panic":true, "print":true,
33 "println":true, "real":true, "recover":true
34 };
35
36 var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
37
38 var curPunc;
39
40 function tokenBase(stream, state) {
41 var ch = stream.next();
42 if (ch == '"' || ch == "'" || ch == "`") {
43 state.tokenize = tokenString(ch);
44 return state.tokenize(stream, state);
45 }
46 if (/[\d\.]/.test(ch)) {
47 if (ch == ".") {
48 stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
49 } else if (ch == "0") {
50 stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
51 } else {
52 stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
53 }
54 return "number";
55 }
56 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
57 curPunc = ch;
58 return null;
59 }
60 if (ch == "/") {
61 if (stream.eat("*")) {
62 state.tokenize = tokenComment;
63 return tokenComment(stream, state);
64 }
65 if (stream.eat("/")) {
66 stream.skipToEnd();
67 return "comment";
68 }
69 }
70 if (isOperatorChar.test(ch)) {
71 stream.eatWhile(isOperatorChar);
72 return "operator";
73 }
74 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
75 var cur = stream.current();
76 if (keywords.propertyIsEnumerable(cur)) {
77 if (cur == "case" || cur == "default") curPunc = "case";
78 return "keyword";
79 }
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
81 return "variable";
82 }
83
84 function tokenString(quote) {
85 return function(stream, state) {
86 var escaped = false, next, end = false;
87 while ((next = stream.next()) != null) {
88 if (next == quote && !escaped) {end = true; break;}
89 escaped = !escaped && next == "\\";
90 }
91 if (end || !(escaped || quote == "`"))
92 state.tokenize = tokenBase;
93 return "string";
94 };
95 }
96
97 function tokenComment(stream, state) {
98 var maybeEnd = false, ch;
99 while (ch = stream.next()) {
100 if (ch == "/" && maybeEnd) {
101 state.tokenize = tokenBase;
102 break;
103 }
104 maybeEnd = (ch == "*");
105 }
106 return "comment";
107 }
108
109 function Context(indented, column, type, align, prev) {
110 this.indented = indented;
111 this.column = column;
112 this.type = type;
113 this.align = align;
114 this.prev = prev;
115 }
116 function pushContext(state, col, type) {
117 return state.context = new Context(state.indented, col, type, null, state.context);
118 }
119 function popContext(state) {
120 var t = state.context.type;
121 if (t == ")" || t == "]" || t == "}")
122 state.indented = state.context.indented;
123 return state.context = state.context.prev;
124 }
125
126 // Interface
127
128 return {
129 startState: function(basecolumn) {
130 return {
131 tokenize: null,
132 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
133 indented: 0,
134 startOfLine: true
135 };
136 },
137
138 token: function(stream, state) {
139 var ctx = state.context;
140 if (stream.sol()) {
141 if (ctx.align == null) ctx.align = false;
142 state.indented = stream.indentation();
143 state.startOfLine = true;
144 if (ctx.type == "case") ctx.type = "}";
145 }
146 if (stream.eatSpace()) return null;
147 curPunc = null;
148 var style = (state.tokenize || tokenBase)(stream, state);
149 if (style == "comment") return style;
150 if (ctx.align == null) ctx.align = true;
151
152 if (curPunc == "{") pushContext(state, stream.column(), "}");
153 else if (curPunc == "[") pushContext(state, stream.column(), "]");
154 else if (curPunc == "(") pushContext(state, stream.column(), ")");
155 else if (curPunc == "case") ctx.type = "case";
156 else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
157 else if (curPunc == ctx.type) popContext(state);
158 state.startOfLine = false;
159 return style;
160 },
161
162 indent: function(state, textAfter) {
163 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
164 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
165 if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
166 state.context.type = "}";
167 return ctx.indented;
168 }
169 var closing = firstChar == ctx.type;
170 if (ctx.align) return ctx.column + (closing ? 0 : 1);
171 else return ctx.indented + (closing ? 0 : indentUnit);
172 },
173
174 electricChars: "{}):",
175 fold: "brace",
176 blockCommentStart: "/*",
177 blockCommentEnd: "*/",
178 lineComment: "//"
179 };
180 });
181
182 CodeMirror.defineMIME("text/x-go", "go");
183
184 });
@@ -1,226 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("groovy", function(config) {
15 function words(str) {
16 var obj = {}, words = str.split(" ");
17 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 return obj;
19 }
20 var keywords = words(
21 "abstract as assert boolean break byte case catch char class const continue def default " +
22 "do double else enum extends final finally float for goto if implements import in " +
23 "instanceof int interface long native new package private protected public return " +
24 "short static strictfp super switch synchronized threadsafe throw throws transient " +
25 "try void volatile while");
26 var blockKeywords = words("catch class do else finally for if switch try while enum interface def");
27 var atoms = words("null true false this");
28
29 var curPunc;
30 function tokenBase(stream, state) {
31 var ch = stream.next();
32 if (ch == '"' || ch == "'") {
33 return startString(ch, stream, state);
34 }
35 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
36 curPunc = ch;
37 return null;
38 }
39 if (/\d/.test(ch)) {
40 stream.eatWhile(/[\w\.]/);
41 if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
42 return "number";
43 }
44 if (ch == "/") {
45 if (stream.eat("*")) {
46 state.tokenize.push(tokenComment);
47 return tokenComment(stream, state);
48 }
49 if (stream.eat("/")) {
50 stream.skipToEnd();
51 return "comment";
52 }
53 if (expectExpression(state.lastToken)) {
54 return startString(ch, stream, state);
55 }
56 }
57 if (ch == "-" && stream.eat(">")) {
58 curPunc = "->";
59 return null;
60 }
61 if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
62 stream.eatWhile(/[+\-*&%=<>|~]/);
63 return "operator";
64 }
65 stream.eatWhile(/[\w\$_]/);
66 if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
67 if (state.lastToken == ".") return "property";
68 if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
69 var cur = stream.current();
70 if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
71 if (keywords.propertyIsEnumerable(cur)) {
72 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
73 return "keyword";
74 }
75 return "variable";
76 }
77 tokenBase.isBase = true;
78
79 function startString(quote, stream, state) {
80 var tripleQuoted = false;
81 if (quote != "/" && stream.eat(quote)) {
82 if (stream.eat(quote)) tripleQuoted = true;
83 else return "string";
84 }
85 function t(stream, state) {
86 var escaped = false, next, end = !tripleQuoted;
87 while ((next = stream.next()) != null) {
88 if (next == quote && !escaped) {
89 if (!tripleQuoted) { break; }
90 if (stream.match(quote + quote)) { end = true; break; }
91 }
92 if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
93 state.tokenize.push(tokenBaseUntilBrace());
94 return "string";
95 }
96 escaped = !escaped && next == "\\";
97 }
98 if (end) state.tokenize.pop();
99 return "string";
100 }
101 state.tokenize.push(t);
102 return t(stream, state);
103 }
104
105 function tokenBaseUntilBrace() {
106 var depth = 1;
107 function t(stream, state) {
108 if (stream.peek() == "}") {
109 depth--;
110 if (depth == 0) {
111 state.tokenize.pop();
112 return state.tokenize[state.tokenize.length-1](stream, state);
113 }
114 } else if (stream.peek() == "{") {
115 depth++;
116 }
117 return tokenBase(stream, state);
118 }
119 t.isBase = true;
120 return t;
121 }
122
123 function tokenComment(stream, state) {
124 var maybeEnd = false, ch;
125 while (ch = stream.next()) {
126 if (ch == "/" && maybeEnd) {
127 state.tokenize.pop();
128 break;
129 }
130 maybeEnd = (ch == "*");
131 }
132 return "comment";
133 }
134
135 function expectExpression(last) {
136 return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
137 last == "newstatement" || last == "keyword" || last == "proplabel";
138 }
139
140 function Context(indented, column, type, align, prev) {
141 this.indented = indented;
142 this.column = column;
143 this.type = type;
144 this.align = align;
145 this.prev = prev;
146 }
147 function pushContext(state, col, type) {
148 return state.context = new Context(state.indented, col, type, null, state.context);
149 }
150 function popContext(state) {
151 var t = state.context.type;
152 if (t == ")" || t == "]" || t == "}")
153 state.indented = state.context.indented;
154 return state.context = state.context.prev;
155 }
156
157 // Interface
158
159 return {
160 startState: function(basecolumn) {
161 return {
162 tokenize: [tokenBase],
163 context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
164 indented: 0,
165 startOfLine: true,
166 lastToken: null
167 };
168 },
169
170 token: function(stream, state) {
171 var ctx = state.context;
172 if (stream.sol()) {
173 if (ctx.align == null) ctx.align = false;
174 state.indented = stream.indentation();
175 state.startOfLine = true;
176 // Automatic semicolon insertion
177 if (ctx.type == "statement" && !expectExpression(state.lastToken)) {
178 popContext(state); ctx = state.context;
179 }
180 }
181 if (stream.eatSpace()) return null;
182 curPunc = null;
183 var style = state.tokenize[state.tokenize.length-1](stream, state);
184 if (style == "comment") return style;
185 if (ctx.align == null) ctx.align = true;
186
187 if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
188 // Handle indentation for {x -> \n ... }
189 else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
190 popContext(state);
191 state.context.align = false;
192 }
193 else if (curPunc == "{") pushContext(state, stream.column(), "}");
194 else if (curPunc == "[") pushContext(state, stream.column(), "]");
195 else if (curPunc == "(") pushContext(state, stream.column(), ")");
196 else if (curPunc == "}") {
197 while (ctx.type == "statement") ctx = popContext(state);
198 if (ctx.type == "}") ctx = popContext(state);
199 while (ctx.type == "statement") ctx = popContext(state);
200 }
201 else if (curPunc == ctx.type) popContext(state);
202 else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
203 pushContext(state, stream.column(), "statement");
204 state.startOfLine = false;
205 state.lastToken = curPunc || style;
206 return style;
207 },
208
209 indent: function(state, textAfter) {
210 if (!state.tokenize[state.tokenize.length-1].isBase) return 0;
211 var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
212 if (ctx.type == "statement" && !expectExpression(state.lastToken)) ctx = ctx.prev;
213 var closing = firstChar == ctx.type;
214 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
215 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
216 else return ctx.indented + (closing ? 0 : config.indentUnit);
217 },
218
219 electricChars: "{}",
220 fold: "brace"
221 };
222 });
223
224 CodeMirror.defineMIME("text/x-groovy", "groovy");
225
226 });
@@ -1,159 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 // full haml mode. This handled embeded ruby and html fragments too
15 CodeMirror.defineMode("haml", function(config) {
16 var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
17 var rubyMode = CodeMirror.getMode(config, "ruby");
18
19 function rubyInQuote(endQuote) {
20 return function(stream, state) {
21 var ch = stream.peek();
22 if (ch == endQuote && state.rubyState.tokenize.length == 1) {
23 // step out of ruby context as it seems to complete processing all the braces
24 stream.next();
25 state.tokenize = html;
26 return "closeAttributeTag";
27 } else {
28 return ruby(stream, state);
29 }
30 };
31 }
32
33 function ruby(stream, state) {
34 if (stream.match("-#")) {
35 stream.skipToEnd();
36 return "comment";
37 }
38 return rubyMode.token(stream, state.rubyState);
39 }
40
41 function html(stream, state) {
42 var ch = stream.peek();
43
44 // handle haml declarations. All declarations that cant be handled here
45 // will be passed to html mode
46 if (state.previousToken.style == "comment" ) {
47 if (state.indented > state.previousToken.indented) {
48 stream.skipToEnd();
49 return "commentLine";
50 }
51 }
52
53 if (state.startOfLine) {
54 if (ch == "!" && stream.match("!!")) {
55 stream.skipToEnd();
56 return "tag";
57 } else if (stream.match(/^%[\w:#\.]+=/)) {
58 state.tokenize = ruby;
59 return "hamlTag";
60 } else if (stream.match(/^%[\w:]+/)) {
61 return "hamlTag";
62 } else if (ch == "/" ) {
63 stream.skipToEnd();
64 return "comment";
65 }
66 }
67
68 if (state.startOfLine || state.previousToken.style == "hamlTag") {
69 if ( ch == "#" || ch == ".") {
70 stream.match(/[\w-#\.]*/);
71 return "hamlAttribute";
72 }
73 }
74
75 // donot handle --> as valid ruby, make it HTML close comment instead
76 if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
77 state.tokenize = ruby;
78 return state.tokenize(stream, state);
79 }
80
81 if (state.previousToken.style == "hamlTag" ||
82 state.previousToken.style == "closeAttributeTag" ||
83 state.previousToken.style == "hamlAttribute") {
84 if (ch == "(") {
85 state.tokenize = rubyInQuote(")");
86 return state.tokenize(stream, state);
87 } else if (ch == "{") {
88 state.tokenize = rubyInQuote("}");
89 return state.tokenize(stream, state);
90 }
91 }
92
93 return htmlMode.token(stream, state.htmlState);
94 }
95
96 return {
97 // default to html mode
98 startState: function() {
99 var htmlState = htmlMode.startState();
100 var rubyState = rubyMode.startState();
101 return {
102 htmlState: htmlState,
103 rubyState: rubyState,
104 indented: 0,
105 previousToken: { style: null, indented: 0},
106 tokenize: html
107 };
108 },
109
110 copyState: function(state) {
111 return {
112 htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
113 rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
114 indented: state.indented,
115 previousToken: state.previousToken,
116 tokenize: state.tokenize
117 };
118 },
119
120 token: function(stream, state) {
121 if (stream.sol()) {
122 state.indented = stream.indentation();
123 state.startOfLine = true;
124 }
125 if (stream.eatSpace()) return null;
126 var style = state.tokenize(stream, state);
127 state.startOfLine = false;
128 // dont record comment line as we only want to measure comment line with
129 // the opening comment block
130 if (style && style != "commentLine") {
131 state.previousToken = { style: style, indented: state.indented };
132 }
133 // if current state is ruby and the previous token is not `,` reset the
134 // tokenize to html
135 if (stream.eol() && state.tokenize == ruby) {
136 stream.backUp(1);
137 var ch = stream.peek();
138 stream.next();
139 if (ch && ch != ",") {
140 state.tokenize = html;
141 }
142 }
143 // reprocess some of the specific style tag when finish setting previousToken
144 if (style == "hamlTag") {
145 style = "tag";
146 } else if (style == "commentLine") {
147 style = "comment";
148 } else if (style == "hamlAttribute") {
149 style = "attribute";
150 } else if (style == "closeAttributeTag") {
151 style = null;
152 }
153 return style;
154 }
155 };
156 }, "htmlmixed", "ruby");
157
158 CodeMirror.defineMIME("text/x-haml", "haml");
159 });
@@ -1,267 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("haskell", function(_config, modeConfig) {
15
16 function switchState(source, setState, f) {
17 setState(f);
18 return f(source, setState);
19 }
20
21 // These should all be Unicode extended, as per the Haskell 2010 report
22 var smallRE = /[a-z_]/;
23 var largeRE = /[A-Z]/;
24 var digitRE = /\d/;
25 var hexitRE = /[0-9A-Fa-f]/;
26 var octitRE = /[0-7]/;
27 var idRE = /[a-z_A-Z0-9'\xa1-\uffff]/;
28 var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/;
29 var specialRE = /[(),;[\]`{}]/;
30 var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
31
32 function normal(source, setState) {
33 if (source.eatWhile(whiteCharRE)) {
34 return null;
35 }
36
37 var ch = source.next();
38 if (specialRE.test(ch)) {
39 if (ch == '{' && source.eat('-')) {
40 var t = "comment";
41 if (source.eat('#')) {
42 t = "meta";
43 }
44 return switchState(source, setState, ncomment(t, 1));
45 }
46 return null;
47 }
48
49 if (ch == '\'') {
50 if (source.eat('\\')) {
51 source.next(); // should handle other escapes here
52 }
53 else {
54 source.next();
55 }
56 if (source.eat('\'')) {
57 return "string";
58 }
59 return "error";
60 }
61
62 if (ch == '"') {
63 return switchState(source, setState, stringLiteral);
64 }
65
66 if (largeRE.test(ch)) {
67 source.eatWhile(idRE);
68 if (source.eat('.')) {
69 return "qualifier";
70 }
71 return "variable-2";
72 }
73
74 if (smallRE.test(ch)) {
75 source.eatWhile(idRE);
76 return "variable";
77 }
78
79 if (digitRE.test(ch)) {
80 if (ch == '0') {
81 if (source.eat(/[xX]/)) {
82 source.eatWhile(hexitRE); // should require at least 1
83 return "integer";
84 }
85 if (source.eat(/[oO]/)) {
86 source.eatWhile(octitRE); // should require at least 1
87 return "number";
88 }
89 }
90 source.eatWhile(digitRE);
91 var t = "number";
92 if (source.match(/^\.\d+/)) {
93 t = "number";
94 }
95 if (source.eat(/[eE]/)) {
96 t = "number";
97 source.eat(/[-+]/);
98 source.eatWhile(digitRE); // should require at least 1
99 }
100 return t;
101 }
102
103 if (ch == "." && source.eat("."))
104 return "keyword";
105
106 if (symbolRE.test(ch)) {
107 if (ch == '-' && source.eat(/-/)) {
108 source.eatWhile(/-/);
109 if (!source.eat(symbolRE)) {
110 source.skipToEnd();
111 return "comment";
112 }
113 }
114 var t = "variable";
115 if (ch == ':') {
116 t = "variable-2";
117 }
118 source.eatWhile(symbolRE);
119 return t;
120 }
121
122 return "error";
123 }
124
125 function ncomment(type, nest) {
126 if (nest == 0) {
127 return normal;
128 }
129 return function(source, setState) {
130 var currNest = nest;
131 while (!source.eol()) {
132 var ch = source.next();
133 if (ch == '{' && source.eat('-')) {
134 ++currNest;
135 }
136 else if (ch == '-' && source.eat('}')) {
137 --currNest;
138 if (currNest == 0) {
139 setState(normal);
140 return type;
141 }
142 }
143 }
144 setState(ncomment(type, currNest));
145 return type;
146 };
147 }
148
149 function stringLiteral(source, setState) {
150 while (!source.eol()) {
151 var ch = source.next();
152 if (ch == '"') {
153 setState(normal);
154 return "string";
155 }
156 if (ch == '\\') {
157 if (source.eol() || source.eat(whiteCharRE)) {
158 setState(stringGap);
159 return "string";
160 }
161 if (source.eat('&')) {
162 }
163 else {
164 source.next(); // should handle other escapes here
165 }
166 }
167 }
168 setState(normal);
169 return "error";
170 }
171
172 function stringGap(source, setState) {
173 if (source.eat('\\')) {
174 return switchState(source, setState, stringLiteral);
175 }
176 source.next();
177 setState(normal);
178 return "error";
179 }
180
181
182 var wellKnownWords = (function() {
183 var wkw = {};
184 function setType(t) {
185 return function () {
186 for (var i = 0; i < arguments.length; i++)
187 wkw[arguments[i]] = t;
188 };
189 }
190
191 setType("keyword")(
192 "case", "class", "data", "default", "deriving", "do", "else", "foreign",
193 "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
194 "module", "newtype", "of", "then", "type", "where", "_");
195
196 setType("keyword")(
197 "\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>");
198
199 setType("builtin")(
200 "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<",
201 "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**");
202
203 setType("builtin")(
204 "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq",
205 "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT",
206 "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",
207 "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",
208 "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",
209 "String", "True");
210
211 setType("builtin")(
212 "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",
213 "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",
214 "compare", "concat", "concatMap", "const", "cos", "cosh", "curry",
215 "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",
216 "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
217 "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",
218 "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",
219 "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",
220 "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",
221 "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",
222 "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",
223 "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",
224 "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",
225 "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",
226 "otherwise", "pi", "pred", "print", "product", "properFraction",
227 "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",
228 "readIO", "readList", "readLn", "readParen", "reads", "readsPrec",
229 "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",
230 "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",
231 "sequence", "sequence_", "show", "showChar", "showList", "showParen",
232 "showString", "shows", "showsPrec", "significand", "signum", "sin",
233 "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",
234 "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",
235 "toRational", "truncate", "uncurry", "undefined", "unlines", "until",
236 "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
237 "zip3", "zipWith", "zipWith3");
238
239 var override = modeConfig.overrideKeywords;
240 if (override) for (var word in override) if (override.hasOwnProperty(word))
241 wkw[word] = override[word];
242
243 return wkw;
244 })();
245
246
247
248 return {
249 startState: function () { return { f: normal }; },
250 copyState: function (s) { return { f: s.f }; },
251
252 token: function(stream, state) {
253 var t = state.f(stream, function(s) { state.f = s; });
254 var w = stream.current();
255 return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t;
256 },
257
258 blockCommentStart: "{-",
259 blockCommentEnd: "-}",
260 lineComment: "--"
261 };
262
263 });
264
265 CodeMirror.defineMIME("text/x-haskell", "haskell");
266
267 });
This diff has been collapsed as it changes many lines, (518 lines changed) Show them Hide them
@@ -1,518 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("haxe", function(config, parserConfig) {
15 var indentUnit = config.indentUnit;
16
17 // Tokenizer
18
19 var keywords = function(){
20 function kw(type) {return {type: type, style: "keyword"};}
21 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
22 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
23 var type = kw("typedef");
24 return {
25 "if": A, "while": A, "else": B, "do": B, "try": B,
26 "return": C, "break": C, "continue": C, "new": C, "throw": C,
27 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
28 "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"),
30 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
31 "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,
33 "true": atom, "false": atom, "null": atom
34 };
35 }();
36
37 var isOperatorChar = /[+\-*&%=<>!?|]/;
38
39 function chain(stream, state, f) {
40 state.tokenize = f;
41 return f(stream, state);
42 }
43
44 function nextUntilUnescaped(stream, end) {
45 var escaped = false, next;
46 while ((next = stream.next()) != null) {
47 if (next == end && !escaped)
48 return false;
49 escaped = !escaped && next == "\\";
50 }
51 return escaped;
52 }
53
54 // Used as scratch variables to communicate multiple values without
55 // consing up tons of objects.
56 var type, content;
57 function ret(tp, style, cont) {
58 type = tp; content = cont;
59 return style;
60 }
61
62 function haxeTokenBase(stream, state) {
63 var ch = stream.next();
64 if (ch == '"' || ch == "'")
65 return chain(stream, state, haxeTokenString(ch));
66 else if (/[\[\]{}\(\),;\:\.]/.test(ch))
67 return ret(ch);
68 else if (ch == "0" && stream.eat(/x/i)) {
69 stream.eatWhile(/[\da-f]/i);
70 return ret("number", "number");
71 }
72 else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
73 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
74 return ret("number", "number");
75 }
76 else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
77 nextUntilUnescaped(stream, "/");
78 stream.eatWhile(/[gimsu]/);
79 return ret("regexp", "string-2");
80 }
81 else if (ch == "/") {
82 if (stream.eat("*")) {
83 return chain(stream, state, haxeTokenComment);
84 }
85 else if (stream.eat("/")) {
86 stream.skipToEnd();
87 return ret("comment", "comment");
88 }
89 else {
90 stream.eatWhile(isOperatorChar);
91 return ret("operator", null, stream.current());
92 }
93 }
94 else if (ch == "#") {
95 stream.skipToEnd();
96 return ret("conditional", "meta");
97 }
98 else if (ch == "@") {
99 stream.eat(/:/);
100 stream.eatWhile(/[\w_]/);
101 return ret ("metadata", "meta");
102 }
103 else if (isOperatorChar.test(ch)) {
104 stream.eatWhile(isOperatorChar);
105 return ret("operator", null, stream.current());
106 }
107 else {
108 var word;
109 if(/[A-Z]/.test(ch))
110 {
111 stream.eatWhile(/[\w_<>]/);
112 word = stream.current();
113 return ret("type", "variable-3", word);
114 }
115 else
116 {
117 stream.eatWhile(/[\w_]/);
118 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
119 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
120 ret("variable", "variable", word);
121 }
122 }
123 }
124
125 function haxeTokenString(quote) {
126 return function(stream, state) {
127 if (!nextUntilUnescaped(stream, quote))
128 state.tokenize = haxeTokenBase;
129 return ret("string", "string");
130 };
131 }
132
133 function haxeTokenComment(stream, state) {
134 var maybeEnd = false, ch;
135 while (ch = stream.next()) {
136 if (ch == "/" && maybeEnd) {
137 state.tokenize = haxeTokenBase;
138 break;
139 }
140 maybeEnd = (ch == "*");
141 }
142 return ret("comment", "comment");
143 }
144
145 // Parser
146
147 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
148
149 function HaxeLexical(indented, column, type, align, prev, info) {
150 this.indented = indented;
151 this.column = column;
152 this.type = type;
153 this.prev = prev;
154 this.info = info;
155 if (align != null) this.align = align;
156 }
157
158 function inScope(state, varname) {
159 for (var v = state.localVars; v; v = v.next)
160 if (v.name == varname) return true;
161 }
162
163 function parseHaxe(state, style, type, content, stream) {
164 var cc = state.cc;
165 // Communicate our context to the combinators.
166 // (Less wasteful than consing up a hundred closures on every call.)
167 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
168
169 if (!state.lexical.hasOwnProperty("align"))
170 state.lexical.align = true;
171
172 while(true) {
173 var combinator = cc.length ? cc.pop() : statement;
174 if (combinator(type, content)) {
175 while(cc.length && cc[cc.length - 1].lex)
176 cc.pop()();
177 if (cx.marked) return cx.marked;
178 if (type == "variable" && inScope(state, content)) return "variable-2";
179 if (type == "variable" && imported(state, content)) return "variable-3";
180 return style;
181 }
182 }
183 }
184
185 function imported(state, typename)
186 {
187 if (/[a-z]/.test(typename.charAt(0)))
188 return false;
189 var len = state.importedtypes.length;
190 for (var i = 0; i<len; i++)
191 if(state.importedtypes[i]==typename) return true;
192 }
193
194
195 function registerimport(importname) {
196 var state = cx.state;
197 for (var t = state.importedtypes; t; t = t.next)
198 if(t.name == importname) return;
199 state.importedtypes = { name: importname, next: state.importedtypes };
200 }
201 // Combinator utils
202
203 var cx = {state: null, column: null, marked: null, cc: null};
204 function pass() {
205 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
206 }
207 function cont() {
208 pass.apply(null, arguments);
209 return true;
210 }
211 function register(varname) {
212 var state = cx.state;
213 if (state.context) {
214 cx.marked = "def";
215 for (var v = state.localVars; v; v = v.next)
216 if (v.name == varname) return;
217 state.localVars = {name: varname, next: state.localVars};
218 }
219 }
220
221 // Combinators
222
223 var defaultVars = {name: "this", next: null};
224 function pushcontext() {
225 if (!cx.state.context) cx.state.localVars = defaultVars;
226 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
227 }
228 function popcontext() {
229 cx.state.localVars = cx.state.context.vars;
230 cx.state.context = cx.state.context.prev;
231 }
232 function pushlex(type, info) {
233 var result = function() {
234 var state = cx.state;
235 state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
236 };
237 result.lex = true;
238 return result;
239 }
240 function poplex() {
241 var state = cx.state;
242 if (state.lexical.prev) {
243 if (state.lexical.type == ")")
244 state.indented = state.lexical.indented;
245 state.lexical = state.lexical.prev;
246 }
247 }
248 poplex.lex = true;
249
250 function expect(wanted) {
251 function f(type) {
252 if (type == wanted) return cont();
253 else if (wanted == ";") return pass();
254 else return cont(f);
255 };
256 return f;
257 }
258
259 function statement(type) {
260 if (type == "@") return cont(metadef);
261 if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
262 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
263 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
264 if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);
265 if (type == ";") return cont();
266 if (type == "attribute") return cont(maybeattribute);
267 if (type == "function") return cont(functiondef);
268 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
269 poplex, statement, poplex);
270 if (type == "variable") return cont(pushlex("stat"), maybelabel);
271 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
272 block, poplex, poplex);
273 if (type == "case") return cont(expression, expect(":"));
274 if (type == "default") return cont(expect(":"));
275 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
276 statement, poplex, popcontext);
277 if (type == "import") return cont(importdef, expect(";"));
278 if (type == "typedef") return cont(typedef);
279 return pass(pushlex("stat"), expression, expect(";"), poplex);
280 }
281 function expression(type) {
282 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
283 if (type == "function") return cont(functiondef);
284 if (type == "keyword c") return cont(maybeexpression);
285 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
286 if (type == "operator") return cont(expression);
287 if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
288 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
289 return cont();
290 }
291 function maybeexpression(type) {
292 if (type.match(/[;\}\)\],]/)) return pass();
293 return pass(expression);
294 }
295
296 function maybeoperator(type, value) {
297 if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
298 if (type == "operator" || type == ":") return cont(expression);
299 if (type == ";") return;
300 if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
301 if (type == ".") return cont(property, maybeoperator);
302 if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
303 }
304
305 function maybeattribute(type) {
306 if (type == "attribute") return cont(maybeattribute);
307 if (type == "function") return cont(functiondef);
308 if (type == "var") return cont(vardef1);
309 }
310
311 function metadef(type) {
312 if(type == ":") return cont(metadef);
313 if(type == "variable") return cont(metadef);
314 if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
315 }
316 function metaargs(type) {
317 if(type == "variable") return cont();
318 }
319
320 function importdef (type, value) {
321 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);
323 }
324
325 function typedef (type, value)
326 {
327 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(); }
329 }
330
331 function maybelabel(type) {
332 if (type == ":") return cont(poplex, statement);
333 return pass(maybeoperator, expect(";"), poplex);
334 }
335 function property(type) {
336 if (type == "variable") {cx.marked = "property"; return cont();}
337 }
338 function objprop(type) {
339 if (type == "variable") cx.marked = "property";
340 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
341 }
342 function commasep(what, end) {
343 function proceed(type) {
344 if (type == ",") return cont(what, proceed);
345 if (type == end) return cont();
346 return cont(expect(end));
347 }
348 return function(type) {
349 if (type == end) return cont();
350 else return pass(what, proceed);
351 };
352 }
353 function block(type) {
354 if (type == "}") return cont();
355 return pass(statement, block);
356 }
357 function vardef1(type, value) {
358 if (type == "variable"){register(value); return cont(typeuse, vardef2);}
359 return cont();
360 }
361 function vardef2(type, value) {
362 if (value == "=") return cont(expression, vardef2);
363 if (type == ",") return cont(vardef1);
364 }
365 function forspec1(type, value) {
366 if (type == "variable") {
367 register(value);
368 }
369 return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);
370 }
371 function forin(_type, value) {
372 if (value == "in") return cont();
373 }
374 function functiondef(type, value) {
375 if (type == "variable") {register(value); return cont(functiondef);}
376 if (value == "new") return cont(functiondef);
377 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
378 }
379 function typeuse(type) {
380 if(type == ":") return cont(typestring);
381 }
382 function typestring(type) {
383 if(type == "type") return cont();
384 if(type == "variable") return cont();
385 if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);
386 }
387 function typeprop(type) {
388 if(type == "variable") return cont(typeuse);
389 }
390 function funarg(type, value) {
391 if (type == "variable") {register(value); return cont(typeuse);}
392 }
393
394 // Interface
395
396 return {
397 startState: function(basecolumn) {
398 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
399 return {
400 tokenize: haxeTokenBase,
401 reAllowed: true,
402 kwAllowed: true,
403 cc: [],
404 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
405 localVars: parserConfig.localVars,
406 importedtypes: defaulttypes,
407 context: parserConfig.localVars && {vars: parserConfig.localVars},
408 indented: 0
409 };
410 },
411
412 token: function(stream, state) {
413 if (stream.sol()) {
414 if (!state.lexical.hasOwnProperty("align"))
415 state.lexical.align = false;
416 state.indented = stream.indentation();
417 }
418 if (stream.eatSpace()) return null;
419 var style = state.tokenize(stream, state);
420 if (type == "comment") return style;
421 state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
422 state.kwAllowed = type != '.';
423 return parseHaxe(state, style, type, content, stream);
424 },
425
426 indent: function(state, textAfter) {
427 if (state.tokenize != haxeTokenBase) return 0;
428 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
429 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
430 var type = lexical.type, closing = firstChar == type;
431 if (type == "vardef") return lexical.indented + 4;
432 else if (type == "form" && firstChar == "{") return lexical.indented;
433 else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
434 else if (lexical.info == "switch" && !closing)
435 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
436 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
437 else return lexical.indented + (closing ? 0 : indentUnit);
438 },
439
440 electricChars: "{}",
441 blockCommentStart: "/*",
442 blockCommentEnd: "*/",
443 lineComment: "//"
444 };
445 });
446
447 CodeMirror.defineMIME("text/x-haxe", "haxe");
448
449 CodeMirror.defineMode("hxml", function () {
450
451 return {
452 startState: function () {
453 return {
454 define: false,
455 inString: false
456 };
457 },
458 token: function (stream, state) {
459 var ch = stream.peek();
460 var sol = stream.sol();
461
462 ///* comments */
463 if (ch == "#") {
464 stream.skipToEnd();
465 return "comment";
466 }
467 if (sol && ch == "-") {
468 var style = "variable-2";
469
470 stream.eat(/-/);
471
472 if (stream.peek() == "-") {
473 stream.eat(/-/);
474 style = "keyword a";
475 }
476
477 if (stream.peek() == "D") {
478 stream.eat(/[D]/);
479 style = "keyword c";
480 state.define = true;
481 }
482
483 stream.eatWhile(/[A-Z]/i);
484 return style;
485 }
486
487 var ch = stream.peek();
488
489 if (state.inString == false && ch == "'") {
490 state.inString = true;
491 ch = stream.next();
492 }
493
494 if (state.inString == true) {
495 if (stream.skipTo("'")) {
496
497 } else {
498 stream.skipToEnd();
499 }
500
501 if (stream.peek() == "'") {
502 stream.next();
503 state.inString = false;
504 }
505
506 return "string";
507 }
508
509 stream.next();
510 return null;
511 },
512 lineComment: "#"
513 };
514 });
515
516 CodeMirror.defineMIME("text/x-hxml", "hxml");
517
518 });
@@ -1,86 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
15
16 //config settings
17 var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
18 scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;
19
20 //inner modes
21 var scriptingMode, htmlMixedMode;
22
23 //tokenizer when in html mode
24 function htmlDispatch(stream, state) {
25 if (stream.match(scriptStartRegex, false)) {
26 state.token=scriptingDispatch;
27 return scriptingMode.token(stream, state.scriptState);
28 }
29 else
30 return htmlMixedMode.token(stream, state.htmlState);
31 }
32
33 //tokenizer when in scripting mode
34 function scriptingDispatch(stream, state) {
35 if (stream.match(scriptEndRegex, false)) {
36 state.token=htmlDispatch;
37 return htmlMixedMode.token(stream, state.htmlState);
38 }
39 else
40 return scriptingMode.token(stream, state.scriptState);
41 }
42
43
44 return {
45 startState: function() {
46 scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
47 htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
48 return {
49 token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
50 htmlState : CodeMirror.startState(htmlMixedMode),
51 scriptState : CodeMirror.startState(scriptingMode)
52 };
53 },
54
55 token: function(stream, state) {
56 return state.token(stream, state);
57 },
58
59 indent: function(state, textAfter) {
60 if (state.token == htmlDispatch)
61 return htmlMixedMode.indent(state.htmlState, textAfter);
62 else if (scriptingMode.indent)
63 return scriptingMode.indent(state.scriptState, textAfter);
64 },
65
66 copyState: function(state) {
67 return {
68 token : state.token,
69 htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
70 scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
71 };
72 },
73
74 innerMode: function(state) {
75 if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
76 else return {state: state.htmlState, mode: htmlMixedMode};
77 }
78 };
79 }, "htmlmixed");
80
81 CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
82 CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
83 CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
84 CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
85
86 });
@@ -1,121 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
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
31 function html(stream, state) {
32 var tagName = state.htmlState.tagName;
33 if (tagName) tagName = tagName.toLowerCase();
34 var style = htmlMode.token(stream, state.htmlState);
35 if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
36 // Script block: mode to change to depends on type attribute
37 var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
38 scriptType = scriptType ? scriptType[1] : "";
39 if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
40 for (var i = 0; i < scriptTypes.length; ++i) {
41 var tp = scriptTypes[i];
42 if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
43 if (tp.mode) {
44 state.token = script;
45 state.localMode = tp.mode;
46 state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
47 }
48 break;
49 }
50 }
51 } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
52 state.token = css;
53 state.localMode = cssMode;
54 state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
55 }
56 return style;
57 }
58 function maybeBackup(stream, pat, style) {
59 var cur = stream.current();
60 var close = cur.search(pat), m;
61 if (close > -1) stream.backUp(cur.length - close);
62 else if (m = cur.match(/<\/?$/)) {
63 stream.backUp(cur.length);
64 if (!stream.match(pat, false)) stream.match(cur);
65 }
66 return style;
67 }
68 function script(stream, state) {
69 if (stream.match(/^<\/\s*script\s*>/i, false)) {
70 state.token = html;
71 state.localState = state.localMode = null;
72 return html(stream, state);
73 }
74 return maybeBackup(stream, /<\/\s*script\s*>/,
75 state.localMode.token(stream, state.localState));
76 }
77 function css(stream, state) {
78 if (stream.match(/^<\/\s*style\s*>/i, false)) {
79 state.token = html;
80 state.localState = state.localMode = null;
81 return html(stream, state);
82 }
83 return maybeBackup(stream, /<\/\s*style\s*>/,
84 cssMode.token(stream, state.localState));
85 }
86
87 return {
88 startState: function() {
89 var state = htmlMode.startState();
90 return {token: html, localMode: null, localState: null, htmlState: state};
91 },
92
93 copyState: function(state) {
94 if (state.localState)
95 var local = CodeMirror.copyState(state.localMode, state.localState);
96 return {token: state.token, localMode: state.localMode, localState: local,
97 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
98 },
99
100 token: function(stream, state) {
101 return state.token(stream, state);
102 },
103
104 indent: function(state, textAfter) {
105 if (!state.localMode || /^\s*<\//.test(textAfter))
106 return htmlMode.indent(state.htmlState, textAfter);
107 else if (state.localMode.indent)
108 return state.localMode.indent(state.localState, textAfter);
109 else
110 return CodeMirror.Pass;
111 },
112
113 innerMode: function(state) {
114 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
115 }
116 };
117 }, "xml", "javascript", "css");
118
119 CodeMirror.defineMIME("text/html", "htmlmixed");
120
121 });
@@ -1,113 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("http", function() {
15 function failFirstLine(stream, state) {
16 stream.skipToEnd();
17 state.cur = header;
18 return "error";
19 }
20
21 function start(stream, state) {
22 if (stream.match(/^HTTP\/\d\.\d/)) {
23 state.cur = responseStatusCode;
24 return "keyword";
25 } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) {
26 state.cur = requestPath;
27 return "keyword";
28 } else {
29 return failFirstLine(stream, state);
30 }
31 }
32
33 function responseStatusCode(stream, state) {
34 var code = stream.match(/^\d+/);
35 if (!code) return failFirstLine(stream, state);
36
37 state.cur = responseStatusText;
38 var status = Number(code[0]);
39 if (status >= 100 && status < 200) {
40 return "positive informational";
41 } else if (status >= 200 && status < 300) {
42 return "positive success";
43 } else if (status >= 300 && status < 400) {
44 return "positive redirect";
45 } else if (status >= 400 && status < 500) {
46 return "negative client-error";
47 } else if (status >= 500 && status < 600) {
48 return "negative server-error";
49 } else {
50 return "error";
51 }
52 }
53
54 function responseStatusText(stream, state) {
55 stream.skipToEnd();
56 state.cur = header;
57 return null;
58 }
59
60 function requestPath(stream, state) {
61 stream.eatWhile(/\S/);
62 state.cur = requestProtocol;
63 return "string-2";
64 }
65
66 function requestProtocol(stream, state) {
67 if (stream.match(/^HTTP\/\d\.\d$/)) {
68 state.cur = header;
69 return "keyword";
70 } else {
71 return failFirstLine(stream, state);
72 }
73 }
74
75 function header(stream) {
76 if (stream.sol() && !stream.eat(/[ \t]/)) {
77 if (stream.match(/^.*?:/)) {
78 return "atom";
79 } else {
80 stream.skipToEnd();
81 return "error";
82 }
83 } else {
84 stream.skipToEnd();
85 return "string";
86 }
87 }
88
89 function body(stream) {
90 stream.skipToEnd();
91 return null;
92 }
93
94 return {
95 token: function(stream, state) {
96 var cur = state.cur;
97 if (cur != header && cur != body && stream.eatSpace()) return null;
98 return cur(stream, state);
99 },
100
101 blankLine: function(state) {
102 state.cur = body;
103 },
104
105 startState: function() {
106 return {cur: start};
107 }
108 };
109 });
110
111 CodeMirror.defineMIME("message/http", "http");
112
113 });
This diff has been collapsed as it changes many lines, (590 lines changed) Show them Hide them
@@ -1,590 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('jade', function (config) {
15 // token types
16 var KEYWORD = 'keyword';
17 var DOCTYPE = 'meta';
18 var ID = 'builtin';
19 var CLASS = 'qualifier';
20
21 var ATTRS_NEST = {
22 '{': '}',
23 '(': ')',
24 '[': ']'
25 };
26
27 var jsMode = CodeMirror.getMode(config, 'javascript');
28
29 function State() {
30 this.javaScriptLine = false;
31 this.javaScriptLineExcludesColon = false;
32
33 this.javaScriptArguments = false;
34 this.javaScriptArgumentsDepth = 0;
35
36 this.isInterpolating = false;
37 this.interpolationNesting = 0;
38
39 this.jsState = jsMode.startState();
40
41 this.restOfLine = '';
42
43 this.isIncludeFiltered = false;
44 this.isEach = false;
45
46 this.lastTag = '';
47 this.scriptType = '';
48
49 // Attributes Mode
50 this.isAttrs = false;
51 this.attrsNest = [];
52 this.inAttributeName = true;
53 this.attributeIsType = false;
54 this.attrValue = '';
55
56 // Indented Mode
57 this.indentOf = Infinity;
58 this.indentToken = '';
59
60 this.innerMode = null;
61 this.innerState = null;
62
63 this.innerModeForLine = false;
64 }
65 /**
66 * Safely copy a state
67 *
68 * @return {State}
69 */
70 State.prototype.copy = function () {
71 var res = new State();
72 res.javaScriptLine = this.javaScriptLine;
73 res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
74 res.javaScriptArguments = this.javaScriptArguments;
75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76 res.isInterpolating = this.isInterpolating;
77 res.interpolationNesting = this.intpolationNesting;
78
79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80
81 res.innerMode = this.innerMode;
82 if (this.innerMode && this.innerState) {
83 res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
84 }
85
86 res.restOfLine = this.restOfLine;
87
88 res.isIncludeFiltered = this.isIncludeFiltered;
89 res.isEach = this.isEach;
90 res.lastTag = this.lastTag;
91 res.scriptType = this.scriptType;
92 res.isAttrs = this.isAttrs;
93 res.attrsNest = this.attrsNest.slice();
94 res.inAttributeName = this.inAttributeName;
95 res.attributeIsType = this.attributeIsType;
96 res.attrValue = this.attrValue;
97 res.indentOf = this.indentOf;
98 res.indentToken = this.indentToken;
99
100 res.innerModeForLine = this.innerModeForLine;
101
102 return res;
103 };
104
105 function javaScript(stream, state) {
106 if (stream.sol()) {
107 // if javaScriptLine was set at end of line, ignore it
108 state.javaScriptLine = false;
109 state.javaScriptLineExcludesColon = false;
110 }
111 if (state.javaScriptLine) {
112 if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
113 state.javaScriptLine = false;
114 state.javaScriptLineExcludesColon = false;
115 return;
116 }
117 var tok = jsMode.token(stream, state.jsState);
118 if (stream.eol()) state.javaScriptLine = false;
119 return tok || true;
120 }
121 }
122 function javaScriptArguments(stream, state) {
123 if (state.javaScriptArguments) {
124 if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
125 state.javaScriptArguments = false;
126 return;
127 }
128 if (stream.peek() === '(') {
129 state.javaScriptArgumentsDepth++;
130 } else if (stream.peek() === ')') {
131 state.javaScriptArgumentsDepth--;
132 }
133 if (state.javaScriptArgumentsDepth === 0) {
134 state.javaScriptArguments = false;
135 return;
136 }
137
138 var tok = jsMode.token(stream, state.jsState);
139 return tok || true;
140 }
141 }
142
143 function yieldStatement(stream) {
144 if (stream.match(/^yield\b/)) {
145 return 'keyword';
146 }
147 }
148
149 function doctype(stream) {
150 if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
151 return DOCTYPE;
152 }
153 }
154
155 function interpolation(stream, state) {
156 if (stream.match('#{')) {
157 state.isInterpolating = true;
158 state.interpolationNesting = 0;
159 return 'punctuation';
160 }
161 }
162
163 function interpolationContinued(stream, state) {
164 if (state.isInterpolating) {
165 if (stream.peek() === '}') {
166 state.interpolationNesting--;
167 if (state.interpolationNesting < 0) {
168 stream.next();
169 state.isInterpolating = false;
170 return 'puncutation';
171 }
172 } else if (stream.peek() === '{') {
173 state.interpolationNesting++;
174 }
175 return jsMode.token(stream, state.jsState) || true;
176 }
177 }
178
179 function caseStatement(stream, state) {
180 if (stream.match(/^case\b/)) {
181 state.javaScriptLine = true;
182 return KEYWORD;
183 }
184 }
185
186 function when(stream, state) {
187 if (stream.match(/^when\b/)) {
188 state.javaScriptLine = true;
189 state.javaScriptLineExcludesColon = true;
190 return KEYWORD;
191 }
192 }
193
194 function defaultStatement(stream) {
195 if (stream.match(/^default\b/)) {
196 return KEYWORD;
197 }
198 }
199
200 function extendsStatement(stream, state) {
201 if (stream.match(/^extends?\b/)) {
202 state.restOfLine = 'string';
203 return KEYWORD;
204 }
205 }
206
207 function append(stream, state) {
208 if (stream.match(/^append\b/)) {
209 state.restOfLine = 'variable';
210 return KEYWORD;
211 }
212 }
213 function prepend(stream, state) {
214 if (stream.match(/^prepend\b/)) {
215 state.restOfLine = 'variable';
216 return KEYWORD;
217 }
218 }
219 function block(stream, state) {
220 if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
221 state.restOfLine = 'variable';
222 return KEYWORD;
223 }
224 }
225
226 function include(stream, state) {
227 if (stream.match(/^include\b/)) {
228 state.restOfLine = 'string';
229 return KEYWORD;
230 }
231 }
232
233 function includeFiltered(stream, state) {
234 if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
235 state.isIncludeFiltered = true;
236 return KEYWORD;
237 }
238 }
239
240 function includeFilteredContinued(stream, state) {
241 if (state.isIncludeFiltered) {
242 var tok = filter(stream, state);
243 state.isIncludeFiltered = false;
244 state.restOfLine = 'string';
245 return tok;
246 }
247 }
248
249 function mixin(stream, state) {
250 if (stream.match(/^mixin\b/)) {
251 state.javaScriptLine = true;
252 return KEYWORD;
253 }
254 }
255
256 function call(stream, state) {
257 if (stream.match(/^\+([-\w]+)/)) {
258 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
259 state.javaScriptArguments = true;
260 state.javaScriptArgumentsDepth = 0;
261 }
262 return 'variable';
263 }
264 if (stream.match(/^\+#{/, false)) {
265 stream.next();
266 state.mixinCallAfter = true;
267 return interpolation(stream, state);
268 }
269 }
270 function callArguments(stream, state) {
271 if (state.mixinCallAfter) {
272 state.mixinCallAfter = false;
273 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
274 state.javaScriptArguments = true;
275 state.javaScriptArgumentsDepth = 0;
276 }
277 return true;
278 }
279 }
280
281 function conditional(stream, state) {
282 if (stream.match(/^(if|unless|else if|else)\b/)) {
283 state.javaScriptLine = true;
284 return KEYWORD;
285 }
286 }
287
288 function each(stream, state) {
289 if (stream.match(/^(- *)?(each|for)\b/)) {
290 state.isEach = true;
291 return KEYWORD;
292 }
293 }
294 function eachContinued(stream, state) {
295 if (state.isEach) {
296 if (stream.match(/^ in\b/)) {
297 state.javaScriptLine = true;
298 state.isEach = false;
299 return KEYWORD;
300 } else if (stream.sol() || stream.eol()) {
301 state.isEach = false;
302 } else if (stream.next()) {
303 while (!stream.match(/^ in\b/, false) && stream.next());
304 return 'variable';
305 }
306 }
307 }
308
309 function whileStatement(stream, state) {
310 if (stream.match(/^while\b/)) {
311 state.javaScriptLine = true;
312 return KEYWORD;
313 }
314 }
315
316 function tag(stream, state) {
317 var captures;
318 if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
319 state.lastTag = captures[1].toLowerCase();
320 if (state.lastTag === 'script') {
321 state.scriptType = 'application/javascript';
322 }
323 return 'tag';
324 }
325 }
326
327 function filter(stream, state) {
328 if (stream.match(/^:([\w\-]+)/)) {
329 var innerMode;
330 if (config && config.innerModes) {
331 innerMode = config.innerModes(stream.current().substring(1));
332 }
333 if (!innerMode) {
334 innerMode = stream.current().substring(1);
335 }
336 if (typeof innerMode === 'string') {
337 innerMode = CodeMirror.getMode(config, innerMode);
338 }
339 setInnerMode(stream, state, innerMode);
340 return 'atom';
341 }
342 }
343
344 function code(stream, state) {
345 if (stream.match(/^(!?=|-)/)) {
346 state.javaScriptLine = true;
347 return 'punctuation';
348 }
349 }
350
351 function id(stream) {
352 if (stream.match(/^#([\w-]+)/)) {
353 return ID;
354 }
355 }
356
357 function className(stream) {
358 if (stream.match(/^\.([\w-]+)/)) {
359 return CLASS;
360 }
361 }
362
363 function attrs(stream, state) {
364 if (stream.peek() == '(') {
365 stream.next();
366 state.isAttrs = true;
367 state.attrsNest = [];
368 state.inAttributeName = true;
369 state.attrValue = '';
370 state.attributeIsType = false;
371 return 'punctuation';
372 }
373 }
374
375 function attrsContinued(stream, state) {
376 if (state.isAttrs) {
377 if (ATTRS_NEST[stream.peek()]) {
378 state.attrsNest.push(ATTRS_NEST[stream.peek()]);
379 }
380 if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
381 state.attrsNest.pop();
382 } else if (stream.eat(')')) {
383 state.isAttrs = false;
384 return 'punctuation';
385 }
386 if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
387 if (stream.peek() === '=' || stream.peek() === '!') {
388 state.inAttributeName = false;
389 state.jsState = jsMode.startState();
390 if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
391 state.attributeIsType = true;
392 } else {
393 state.attributeIsType = false;
394 }
395 }
396 return 'attribute';
397 }
398
399 var tok = jsMode.token(stream, state.jsState);
400 if (state.attributeIsType && tok === 'string') {
401 state.scriptType = stream.current().toString();
402 }
403 if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
404 try {
405 Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
406 state.inAttributeName = true;
407 state.attrValue = '';
408 stream.backUp(stream.current().length);
409 return attrsContinued(stream, state);
410 } catch (ex) {
411 //not the end of an attribute
412 }
413 }
414 state.attrValue += stream.current();
415 return tok || true;
416 }
417 }
418
419 function attributesBlock(stream, state) {
420 if (stream.match(/^&attributes\b/)) {
421 state.javaScriptArguments = true;
422 state.javaScriptArgumentsDepth = 0;
423 return 'keyword';
424 }
425 }
426
427 function indent(stream) {
428 if (stream.sol() && stream.eatSpace()) {
429 return 'indent';
430 }
431 }
432
433 function comment(stream, state) {
434 if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
435 state.indentOf = stream.indentation();
436 state.indentToken = 'comment';
437 return 'comment';
438 }
439 }
440
441 function colon(stream) {
442 if (stream.match(/^: */)) {
443 return 'colon';
444 }
445 }
446
447 function text(stream, state) {
448 if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
449 return 'string';
450 }
451 if (stream.match(/^(<[^\n]*)/, false)) {
452 // html string
453 setInnerMode(stream, state, 'htmlmixed');
454 state.innerModeForLine = true;
455 return innerMode(stream, state, true);
456 }
457 }
458
459 function dot(stream, state) {
460 if (stream.eat('.')) {
461 var innerMode = null;
462 if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
463 innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
464 } else if (state.lastTag === 'style') {
465 innerMode = 'css';
466 }
467 setInnerMode(stream, state, innerMode);
468 return 'dot';
469 }
470 }
471
472 function fail(stream) {
473 stream.next();
474 return null;
475 }
476
477
478 function setInnerMode(stream, state, mode) {
479 mode = CodeMirror.mimeModes[mode] || mode;
480 mode = config.innerModes ? config.innerModes(mode) || mode : mode;
481 mode = CodeMirror.mimeModes[mode] || mode;
482 mode = CodeMirror.getMode(config, mode);
483 state.indentOf = stream.indentation();
484
485 if (mode && mode.name !== 'null') {
486 state.innerMode = mode;
487 } else {
488 state.indentToken = 'string';
489 }
490 }
491 function innerMode(stream, state, force) {
492 if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
493 if (state.innerMode) {
494 if (!state.innerState) {
495 state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
496 }
497 return stream.hideFirstChars(state.indentOf + 2, function () {
498 return state.innerMode.token(stream, state.innerState) || true;
499 });
500 } else {
501 stream.skipToEnd();
502 return state.indentToken;
503 }
504 } else if (stream.sol()) {
505 state.indentOf = Infinity;
506 state.indentToken = null;
507 state.innerMode = null;
508 state.innerState = null;
509 }
510 }
511 function restOfLine(stream, state) {
512 if (stream.sol()) {
513 // if restOfLine was set at end of line, ignore it
514 state.restOfLine = '';
515 }
516 if (state.restOfLine) {
517 stream.skipToEnd();
518 var tok = state.restOfLine;
519 state.restOfLine = '';
520 return tok;
521 }
522 }
523
524
525 function startState() {
526 return new State();
527 }
528 function copyState(state) {
529 return state.copy();
530 }
531 /**
532 * Get the next token in the stream
533 *
534 * @param {Stream} stream
535 * @param {State} state
536 */
537 function nextToken(stream, state) {
538 var tok = innerMode(stream, state)
539 || restOfLine(stream, state)
540 || interpolationContinued(stream, state)
541 || includeFilteredContinued(stream, state)
542 || eachContinued(stream, state)
543 || attrsContinued(stream, state)
544 || javaScript(stream, state)
545 || javaScriptArguments(stream, state)
546 || callArguments(stream, state)
547
548 || yieldStatement(stream, state)
549 || doctype(stream, state)
550 || interpolation(stream, state)
551 || caseStatement(stream, state)
552 || when(stream, state)
553 || defaultStatement(stream, state)
554 || extendsStatement(stream, state)
555 || append(stream, state)
556 || prepend(stream, state)
557 || block(stream, state)
558 || include(stream, state)
559 || includeFiltered(stream, state)
560 || mixin(stream, state)
561 || call(stream, state)
562 || conditional(stream, state)
563 || each(stream, state)
564 || whileStatement(stream, state)
565 || tag(stream, state)
566 || filter(stream, state)
567 || code(stream, state)
568 || id(stream, state)
569 || className(stream, state)
570 || attrs(stream, state)
571 || attributesBlock(stream, state)
572 || indent(stream, state)
573 || text(stream, state)
574 || comment(stream, state)
575 || colon(stream, state)
576 || dot(stream, state)
577 || fail(stream, state);
578
579 return tok === true ? null : tok;
580 }
581 return {
582 startState: startState,
583 copyState: copyState,
584 token: nextToken
585 };
586 });
587
588 CodeMirror.defineMIME('text/x-jade', 'jade');
589
590 });
This diff has been collapsed as it changes many lines, (684 lines changed) Show them Hide them
@@ -1,684 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // TODO actually recognize syntax of TypeScript constructs
5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMode("javascript", function(config, parserConfig) {
17 var indentUnit = config.indentUnit;
18 var statementIndent = parserConfig.statementIndent;
19 var jsonldMode = parserConfig.jsonld;
20 var jsonMode = parserConfig.json || jsonldMode;
21 var isTS = parserConfig.typescript;
22 var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
23
24 // Tokenizer
25
26 var keywords = function(){
27 function kw(type) {return {type: type, style: "keyword"};}
28 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
29 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
30
31 var jsKeywords = {
32 "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,
34 "var": kw("var"), "const": kw("var"), "let": kw("var"),
35 "function": kw("function"), "catch": kw("catch"),
36 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
37 "in": operator, "typeof": operator, "instanceof": operator,
38 "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"),
40 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
41 };
42
43 // Extend the 'normal' keywords with the TypeScript language extensions
44 if (isTS) {
45 var type = {type: "variable", style: "variable-3"};
46 var tsKeywords = {
47 // object-like things
48 "interface": kw("interface"),
49 "extends": kw("extends"),
50 "constructor": kw("constructor"),
51
52 // scope modifiers
53 "public": kw("public"),
54 "private": kw("private"),
55 "protected": kw("protected"),
56 "static": kw("static"),
57
58 // types
59 "string": type, "number": type, "bool": type, "any": type
60 };
61
62 for (var attr in tsKeywords) {
63 jsKeywords[attr] = tsKeywords[attr];
64 }
65 }
66
67 return jsKeywords;
68 }();
69
70 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
71 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
72
73 function readRegexp(stream) {
74 var escaped = false, next, inSet = false;
75 while ((next = stream.next()) != null) {
76 if (!escaped) {
77 if (next == "/" && !inSet) return;
78 if (next == "[") inSet = true;
79 else if (inSet && next == "]") inSet = false;
80 }
81 escaped = !escaped && next == "\\";
82 }
83 }
84
85 // Used as scratch variables to communicate multiple values without
86 // consing up tons of objects.
87 var type, content;
88 function ret(tp, style, cont) {
89 type = tp; content = cont;
90 return style;
91 }
92 function tokenBase(stream, state) {
93 var ch = stream.next();
94 if (ch == '"' || ch == "'") {
95 state.tokenize = tokenString(ch);
96 return state.tokenize(stream, state);
97 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
98 return ret("number", "number");
99 } else if (ch == "." && stream.match("..")) {
100 return ret("spread", "meta");
101 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
102 return ret(ch);
103 } else if (ch == "=" && stream.eat(">")) {
104 return ret("=>", "operator");
105 } else if (ch == "0" && stream.eat(/x/i)) {
106 stream.eatWhile(/[\da-f]/i);
107 return ret("number", "number");
108 } else if (/\d/.test(ch)) {
109 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
110 return ret("number", "number");
111 } else if (ch == "/") {
112 if (stream.eat("*")) {
113 state.tokenize = tokenComment;
114 return tokenComment(stream, state);
115 } else if (stream.eat("/")) {
116 stream.skipToEnd();
117 return ret("comment", "comment");
118 } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
119 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
120 readRegexp(stream);
121 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
122 return ret("regexp", "string-2");
123 } else {
124 stream.eatWhile(isOperatorChar);
125 return ret("operator", "operator", stream.current());
126 }
127 } else if (ch == "`") {
128 state.tokenize = tokenQuasi;
129 return tokenQuasi(stream, state);
130 } else if (ch == "#") {
131 stream.skipToEnd();
132 return ret("error", "error");
133 } else if (isOperatorChar.test(ch)) {
134 stream.eatWhile(isOperatorChar);
135 return ret("operator", "operator", stream.current());
136 } else if (wordRE.test(ch)) {
137 stream.eatWhile(wordRE);
138 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
139 return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
140 ret("variable", "variable", word);
141 }
142 }
143
144 function tokenString(quote) {
145 return function(stream, state) {
146 var escaped = false, next;
147 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
148 state.tokenize = tokenBase;
149 return ret("jsonld-keyword", "meta");
150 }
151 while ((next = stream.next()) != null) {
152 if (next == quote && !escaped) break;
153 escaped = !escaped && next == "\\";
154 }
155 if (!escaped) state.tokenize = tokenBase;
156 return ret("string", "string");
157 };
158 }
159
160 function tokenComment(stream, state) {
161 var maybeEnd = false, ch;
162 while (ch = stream.next()) {
163 if (ch == "/" && maybeEnd) {
164 state.tokenize = tokenBase;
165 break;
166 }
167 maybeEnd = (ch == "*");
168 }
169 return ret("comment", "comment");
170 }
171
172 function tokenQuasi(stream, state) {
173 var escaped = false, next;
174 while ((next = stream.next()) != null) {
175 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
176 state.tokenize = tokenBase;
177 break;
178 }
179 escaped = !escaped && next == "\\";
180 }
181 return ret("quasi", "string-2", stream.current());
182 }
183
184 var brackets = "([{}])";
185 // 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
187 // 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
189 // (comments) in between. Fallback is to only notice when we hit the
190 // arrow, and not declare the arguments as locals for the arrow
191 // body.
192 function findFatArrow(stream, state) {
193 if (state.fatArrowAt) state.fatArrowAt = null;
194 var arrow = stream.string.indexOf("=>", stream.start);
195 if (arrow < 0) return;
196
197 var depth = 0, sawSomething = false;
198 for (var pos = arrow - 1; pos >= 0; --pos) {
199 var ch = stream.string.charAt(pos);
200 var bracket = brackets.indexOf(ch);
201 if (bracket >= 0 && bracket < 3) {
202 if (!depth) { ++pos; break; }
203 if (--depth == 0) break;
204 } else if (bracket >= 3 && bracket < 6) {
205 ++depth;
206 } else if (wordRE.test(ch)) {
207 sawSomething = true;
208 } else if (sawSomething && !depth) {
209 ++pos;
210 break;
211 }
212 }
213 if (sawSomething && !depth) state.fatArrowAt = pos;
214 }
215
216 // Parser
217
218 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
219
220 function JSLexical(indented, column, type, align, prev, info) {
221 this.indented = indented;
222 this.column = column;
223 this.type = type;
224 this.prev = prev;
225 this.info = info;
226 if (align != null) this.align = align;
227 }
228
229 function inScope(state, varname) {
230 for (var v = state.localVars; v; v = v.next)
231 if (v.name == varname) return true;
232 for (var cx = state.context; cx; cx = cx.prev) {
233 for (var v = cx.vars; v; v = v.next)
234 if (v.name == varname) return true;
235 }
236 }
237
238 function parseJS(state, style, type, content, stream) {
239 var cc = state.cc;
240 // Communicate our context to the combinators.
241 // (Less wasteful than consing up a hundred closures on every call.)
242 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
243
244 if (!state.lexical.hasOwnProperty("align"))
245 state.lexical.align = true;
246
247 while(true) {
248 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
249 if (combinator(type, content)) {
250 while(cc.length && cc[cc.length - 1].lex)
251 cc.pop()();
252 if (cx.marked) return cx.marked;
253 if (type == "variable" && inScope(state, content)) return "variable-2";
254 return style;
255 }
256 }
257 }
258
259 // Combinator utils
260
261 var cx = {state: null, column: null, marked: null, cc: null};
262 function pass() {
263 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
264 }
265 function cont() {
266 pass.apply(null, arguments);
267 return true;
268 }
269 function register(varname) {
270 function inList(list) {
271 for (var v = list; v; v = v.next)
272 if (v.name == varname) return true;
273 return false;
274 }
275 var state = cx.state;
276 if (state.context) {
277 cx.marked = "def";
278 if (inList(state.localVars)) return;
279 state.localVars = {name: varname, next: state.localVars};
280 } else {
281 if (inList(state.globalVars)) return;
282 if (parserConfig.globalVars)
283 state.globalVars = {name: varname, next: state.globalVars};
284 }
285 }
286
287 // Combinators
288
289 var defaultVars = {name: "this", next: {name: "arguments"}};
290 function pushcontext() {
291 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
292 cx.state.localVars = defaultVars;
293 }
294 function popcontext() {
295 cx.state.localVars = cx.state.context.vars;
296 cx.state.context = cx.state.context.prev;
297 }
298 function pushlex(type, info) {
299 var result = function() {
300 var state = cx.state, indent = state.indented;
301 if (state.lexical.type == "stat") indent = state.lexical.indented;
302 else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
303 indent = outer.indented;
304 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
305 };
306 result.lex = true;
307 return result;
308 }
309 function poplex() {
310 var state = cx.state;
311 if (state.lexical.prev) {
312 if (state.lexical.type == ")")
313 state.indented = state.lexical.indented;
314 state.lexical = state.lexical.prev;
315 }
316 }
317 poplex.lex = true;
318
319 function expect(wanted) {
320 function exp(type) {
321 if (type == wanted) return cont();
322 else if (wanted == ";") return pass();
323 else return cont(exp);
324 };
325 return exp;
326 }
327
328 function statement(type, value) {
329 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
330 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
331 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
332 if (type == "{") return cont(pushlex("}"), block, poplex);
333 if (type == ";") return cont();
334 if (type == "if") {
335 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
336 cx.state.cc.pop()();
337 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
338 }
339 if (type == "function") return cont(functiondef);
340 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
341 if (type == "variable") return cont(pushlex("stat"), maybelabel);
342 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
343 block, poplex, poplex);
344 if (type == "case") return cont(expression, expect(":"));
345 if (type == "default") return cont(expect(":"));
346 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
347 statement, poplex, popcontext);
348 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
349 if (type == "class") return cont(pushlex("form"), className, poplex);
350 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
351 if (type == "import") return cont(pushlex("form"), afterImport, poplex);
352 return pass(pushlex("stat"), expression, expect(";"), poplex);
353 }
354 function expression(type) {
355 return expressionInner(type, false);
356 }
357 function expressionNoComma(type) {
358 return expressionInner(type, true);
359 }
360 function expressionInner(type, noComma) {
361 if (cx.state.fatArrowAt == cx.stream.start) {
362 var body = noComma ? arrowBodyNoComma : arrowBody;
363 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
364 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
365 }
366
367 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
368 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
369 if (type == "function") return cont(functiondef, maybeop);
370 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
371 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
372 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
373 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
374 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
375 if (type == "quasi") { return pass(quasi, maybeop); }
376 return cont();
377 }
378 function maybeexpression(type) {
379 if (type.match(/[;\}\)\],]/)) return pass();
380 return pass(expression);
381 }
382 function maybeexpressionNoComma(type) {
383 if (type.match(/[;\}\)\],]/)) return pass();
384 return pass(expressionNoComma);
385 }
386
387 function maybeoperatorComma(type, value) {
388 if (type == ",") return cont(expression);
389 return maybeoperatorNoComma(type, value, false);
390 }
391 function maybeoperatorNoComma(type, value, noComma) {
392 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
393 var expr = noComma == false ? expression : expressionNoComma;
394 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
395 if (type == "operator") {
396 if (/\+\+|--/.test(value)) return cont(me);
397 if (value == "?") return cont(expression, expect(":"), expr);
398 return cont(expr);
399 }
400 if (type == "quasi") { return pass(quasi, me); }
401 if (type == ";") return;
402 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
403 if (type == ".") return cont(property, me);
404 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
405 }
406 function quasi(type, value) {
407 if (type != "quasi") return pass();
408 if (value.slice(value.length - 2) != "${") return cont(quasi);
409 return cont(expression, continueQuasi);
410 }
411 function continueQuasi(type) {
412 if (type == "}") {
413 cx.marked = "string-2";
414 cx.state.tokenize = tokenQuasi;
415 return cont(quasi);
416 }
417 }
418 function arrowBody(type) {
419 findFatArrow(cx.stream, cx.state);
420 return pass(type == "{" ? statement : expression);
421 }
422 function arrowBodyNoComma(type) {
423 findFatArrow(cx.stream, cx.state);
424 return pass(type == "{" ? statement : expressionNoComma);
425 }
426 function maybelabel(type) {
427 if (type == ":") return cont(poplex, statement);
428 return pass(maybeoperatorComma, expect(";"), poplex);
429 }
430 function property(type) {
431 if (type == "variable") {cx.marked = "property"; return cont();}
432 }
433 function objprop(type, value) {
434 if (type == "variable" || cx.style == "keyword") {
435 cx.marked = "property";
436 if (value == "get" || value == "set") return cont(getterSetter);
437 return cont(afterprop);
438 } else if (type == "number" || type == "string") {
439 cx.marked = jsonldMode ? "property" : (cx.style + " property");
440 return cont(afterprop);
441 } else if (type == "jsonld-keyword") {
442 return cont(afterprop);
443 } else if (type == "[") {
444 return cont(expression, expect("]"), afterprop);
445 }
446 }
447 function getterSetter(type) {
448 if (type != "variable") return pass(afterprop);
449 cx.marked = "property";
450 return cont(functiondef);
451 }
452 function afterprop(type) {
453 if (type == ":") return cont(expressionNoComma);
454 if (type == "(") return pass(functiondef);
455 }
456 function commasep(what, end) {
457 function proceed(type) {
458 if (type == ",") {
459 var lex = cx.state.lexical;
460 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
461 return cont(what, proceed);
462 }
463 if (type == end) return cont();
464 return cont(expect(end));
465 }
466 return function(type) {
467 if (type == end) return cont();
468 return pass(what, proceed);
469 };
470 }
471 function contCommasep(what, end, info) {
472 for (var i = 3; i < arguments.length; i++)
473 cx.cc.push(arguments[i]);
474 return cont(pushlex(end, info), commasep(what, end), poplex);
475 }
476 function block(type) {
477 if (type == "}") return cont();
478 return pass(statement, block);
479 }
480 function maybetype(type) {
481 if (isTS && type == ":") return cont(typedef);
482 }
483 function typedef(type) {
484 if (type == "variable"){cx.marked = "variable-3"; return cont();}
485 }
486 function vardef() {
487 return pass(pattern, maybetype, maybeAssign, vardefCont);
488 }
489 function pattern(type, value) {
490 if (type == "variable") { register(value); return cont(); }
491 if (type == "[") return contCommasep(pattern, "]");
492 if (type == "{") return contCommasep(proppattern, "}");
493 }
494 function proppattern(type, value) {
495 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
496 register(value);
497 return cont(maybeAssign);
498 }
499 if (type == "variable") cx.marked = "property";
500 return cont(expect(":"), pattern, maybeAssign);
501 }
502 function maybeAssign(_type, value) {
503 if (value == "=") return cont(expressionNoComma);
504 }
505 function vardefCont(type) {
506 if (type == ",") return cont(vardef);
507 }
508 function maybeelse(type, value) {
509 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
510 }
511 function forspec(type) {
512 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
513 }
514 function forspec1(type) {
515 if (type == "var") return cont(vardef, expect(";"), forspec2);
516 if (type == ";") return cont(forspec2);
517 if (type == "variable") return cont(formaybeinof);
518 return pass(expression, expect(";"), forspec2);
519 }
520 function formaybeinof(_type, value) {
521 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
522 return cont(maybeoperatorComma, forspec2);
523 }
524 function forspec2(type, value) {
525 if (type == ";") return cont(forspec3);
526 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
527 return pass(expression, expect(";"), forspec3);
528 }
529 function forspec3(type) {
530 if (type != ")") cont(expression);
531 }
532 function functiondef(type, value) {
533 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
534 if (type == "variable") {register(value); return cont(functiondef);}
535 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
536 }
537 function funarg(type) {
538 if (type == "spread") return cont(funarg);
539 return pass(pattern, maybetype);
540 }
541 function className(type, value) {
542 if (type == "variable") {register(value); return cont(classNameAfter);}
543 }
544 function classNameAfter(type, value) {
545 if (value == "extends") return cont(expression, classNameAfter);
546 if (type == "{") return cont(pushlex("}"), classBody, poplex);
547 }
548 function classBody(type, value) {
549 if (type == "variable" || cx.style == "keyword") {
550 cx.marked = "property";
551 if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
552 return cont(functiondef, classBody);
553 }
554 if (value == "*") {
555 cx.marked = "keyword";
556 return cont(classBody);
557 }
558 if (type == ";") return cont(classBody);
559 if (type == "}") return cont();
560 }
561 function classGetterSetter(type) {
562 if (type != "variable") return pass();
563 cx.marked = "property";
564 return cont();
565 }
566 function afterModule(type, value) {
567 if (type == "string") return cont(statement);
568 if (type == "variable") { register(value); return cont(maybeFrom); }
569 }
570 function afterExport(_type, value) {
571 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
572 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
573 return pass(statement);
574 }
575 function afterImport(type) {
576 if (type == "string") return cont();
577 return pass(importSpec, maybeFrom);
578 }
579 function importSpec(type, value) {
580 if (type == "{") return contCommasep(importSpec, "}");
581 if (type == "variable") register(value);
582 return cont();
583 }
584 function maybeFrom(_type, value) {
585 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
586 }
587 function arrayLiteral(type) {
588 if (type == "]") return cont();
589 return pass(expressionNoComma, maybeArrayComprehension);
590 }
591 function maybeArrayComprehension(type) {
592 if (type == "for") return pass(comprehension, expect("]"));
593 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
594 return pass(commasep(expressionNoComma, "]"));
595 }
596 function comprehension(type) {
597 if (type == "for") return cont(forspec, comprehension);
598 if (type == "if") return cont(expression, comprehension);
599 }
600
601 // Interface
602
603 return {
604 startState: function(basecolumn) {
605 var state = {
606 tokenize: tokenBase,
607 lastType: "sof",
608 cc: [],
609 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
610 localVars: parserConfig.localVars,
611 context: parserConfig.localVars && {vars: parserConfig.localVars},
612 indented: 0
613 };
614 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
615 state.globalVars = parserConfig.globalVars;
616 return state;
617 },
618
619 token: function(stream, state) {
620 if (stream.sol()) {
621 if (!state.lexical.hasOwnProperty("align"))
622 state.lexical.align = false;
623 state.indented = stream.indentation();
624 findFatArrow(stream, state);
625 }
626 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
627 var style = state.tokenize(stream, state);
628 if (type == "comment") return style;
629 state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
630 return parseJS(state, style, type, content, stream);
631 },
632
633 indent: function(state, textAfter) {
634 if (state.tokenize == tokenComment) return CodeMirror.Pass;
635 if (state.tokenize != tokenBase) return 0;
636 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
637 // Kludge to prevent 'maybelse' from blocking lexical scope pops
638 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
639 var c = state.cc[i];
640 if (c == poplex) lexical = lexical.prev;
641 else if (c != maybeelse) break;
642 }
643 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
644 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
645 lexical = lexical.prev;
646 var type = lexical.type, closing = firstChar == type;
647
648 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
649 else if (type == "form" && firstChar == "{") return lexical.indented;
650 else if (type == "form") return lexical.indented + indentUnit;
651 else if (type == "stat")
652 return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
653 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
654 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
655 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
656 else return lexical.indented + (closing ? 0 : indentUnit);
657 },
658
659 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
660 blockCommentStart: jsonMode ? null : "/*",
661 blockCommentEnd: jsonMode ? null : "*/",
662 lineComment: jsonMode ? null : "//",
663 fold: "brace",
664
665 helperType: jsonMode ? "json" : "javascript",
666 jsonldMode: jsonldMode,
667 jsonMode: jsonMode
668 };
669 });
670
671 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
672
673 CodeMirror.defineMIME("text/javascript", "javascript");
674 CodeMirror.defineMIME("text/ecmascript", "javascript");
675 CodeMirror.defineMIME("application/javascript", "javascript");
676 CodeMirror.defineMIME("application/x-javascript", "javascript");
677 CodeMirror.defineMIME("application/ecmascript", "javascript");
678 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
679 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
680 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
681 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
682 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
683
684 });
@@ -1,142 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("jinja2", function() {
15 var keywords = ["and", "as", "block", "endblock", "by", "cycle", "debug", "else", "elif",
16 "extends", "filter", "endfilter", "firstof", "for",
17 "endfor", "if", "endif", "ifchanged", "endifchanged",
18 "ifequal", "endifequal", "ifnotequal",
19 "endifnotequal", "in", "include", "load", "not", "now", "or",
20 "parsed", "regroup", "reversed", "spaceless",
21 "endspaceless", "ssi", "templatetag", "openblock",
22 "closeblock", "openvariable", "closevariable",
23 "openbrace", "closebrace", "opencomment",
24 "closecomment", "widthratio", "url", "with", "endwith",
25 "get_current_language", "trans", "endtrans", "noop", "blocktrans",
26 "endblocktrans", "get_available_languages",
27 "get_current_language_bidi", "plural"],
28 operator = /^[+\-*&%=<>!?|~^]/,
29 sign = /^[:\[\(\{]/,
30 atom = ["true", "false"],
31 number = /^(\d[+\-\*\/])?\d+(\.\d+)?/;
32
33 keywords = new RegExp("((" + keywords.join(")|(") + "))\\b");
34 atom = new RegExp("((" + atom.join(")|(") + "))\\b");
35
36 function tokenBase (stream, state) {
37 var ch = stream.peek();
38
39 //Comment
40 if (state.incomment) {
41 if(!stream.skipTo("#}")) {
42 stream.skipToEnd();
43 } else {
44 stream.eatWhile(/\#|}/);
45 state.incomment = false;
46 }
47 return "comment";
48 //Tag
49 } else if (state.intag) {
50 //After operator
51 if(state.operator) {
52 state.operator = false;
53 if(stream.match(atom)) {
54 return "atom";
55 }
56 if(stream.match(number)) {
57 return "number";
58 }
59 }
60 //After sign
61 if(state.sign) {
62 state.sign = false;
63 if(stream.match(atom)) {
64 return "atom";
65 }
66 if(stream.match(number)) {
67 return "number";
68 }
69 }
70
71 if(state.instring) {
72 if(ch == state.instring) {
73 state.instring = false;
74 }
75 stream.next();
76 return "string";
77 } else if(ch == "'" || ch == '"') {
78 state.instring = ch;
79 stream.next();
80 return "string";
81 } else if(stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) {
82 state.intag = false;
83 return "tag";
84 } else if(stream.match(operator)) {
85 state.operator = true;
86 return "operator";
87 } else if(stream.match(sign)) {
88 state.sign = true;
89 } else {
90 if(stream.eat(" ") || stream.sol()) {
91 if(stream.match(keywords)) {
92 return "keyword";
93 }
94 if(stream.match(atom)) {
95 return "atom";
96 }
97 if(stream.match(number)) {
98 return "number";
99 }
100 if(stream.sol()) {
101 stream.next();
102 }
103 } else {
104 stream.next();
105 }
106
107 }
108 return "variable";
109 } else if (stream.eat("{")) {
110 if (ch = stream.eat("#")) {
111 state.incomment = true;
112 if(!stream.skipTo("#}")) {
113 stream.skipToEnd();
114 } else {
115 stream.eatWhile(/\#|}/);
116 state.incomment = false;
117 }
118 return "comment";
119 //Open tag
120 } else if (ch = stream.eat(/\{|%/)) {
121 //Cache close tag
122 state.intag = ch;
123 if(ch == "{") {
124 state.intag = "}";
125 }
126 stream.eat("-");
127 return "tag";
128 }
129 }
130 stream.next();
131 };
132
133 return {
134 startState: function () {
135 return {tokenize: tokenBase};
136 },
137 token: function (stream, state) {
138 return state.tokenize(stream, state);
139 }
140 };
141 });
142 });
@@ -1,301 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("julia", function(_conf, parserConf) {
15 var ERRORCLASS = 'error';
16
17 function wordRegexp(words) {
18 return new RegExp("^((" + words.join(")|(") + "))\\b");
19 }
20
21 var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b/;
22 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
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"];
25 var blockClosers = ["end", "else", "elseif", "catch", "finally"];
26 var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype', 'ccall'];
27 var builtinList = ['true', 'false', 'enumerate', 'open', 'close', 'nothing', 'NaN', 'Inf', 'print', 'println', 'Int', 'Int8', 'Uint8', 'Int16', 'Uint16', 'Int32', 'Uint32', 'Int64', 'Uint64', 'Int128', 'Uint128', 'Bool', 'Char', 'Float16', 'Float32', 'Float64', 'Array', 'Vector', 'Matrix', 'String', 'UTF8String', 'ASCIIString', 'error', 'warn', 'info', '@printf'];
28
29 //var stringPrefixes = new RegExp("^[br]?('|\")")
30 var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
31 var keywords = wordRegexp(keywordList);
32 var builtins = wordRegexp(builtinList);
33 var openers = wordRegexp(blockOpeners);
34 var closers = wordRegexp(blockClosers);
35 var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
36 var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
37 var indentInfo = null;
38
39 function in_array(state) {
40 var ch = cur_scope(state);
41 if(ch=="[" || ch=="{") {
42 return true;
43 }
44 else {
45 return false;
46 }
47 }
48
49 function cur_scope(state) {
50 if(state.scopes.length==0) {
51 return null;
52 }
53 return state.scopes[state.scopes.length - 1];
54 }
55
56 // tokenizers
57 function tokenBase(stream, state) {
58 // Handle scope changes
59 var leaving_expr = state.leaving_expr;
60 if(stream.sol()) {
61 leaving_expr = false;
62 }
63 state.leaving_expr = false;
64 if(leaving_expr) {
65 if(stream.match(/^'+/)) {
66 return 'operator';
67 }
68
69 }
70
71 if(stream.match(/^\.{2,3}/)) {
72 return 'operator';
73 }
74
75 if (stream.eatSpace()) {
76 return null;
77 }
78
79 var ch = stream.peek();
80 // Handle Comments
81 if (ch === '#') {
82 stream.skipToEnd();
83 return 'comment';
84 }
85 if(ch==='[') {
86 state.scopes.push("[");
87 }
88
89 if(ch==='{') {
90 state.scopes.push("{");
91 }
92
93 var scope=cur_scope(state);
94
95 if(scope==='[' && ch===']') {
96 state.scopes.pop();
97 state.leaving_expr=true;
98 }
99
100 if(scope==='{' && ch==='}') {
101 state.scopes.pop();
102 state.leaving_expr=true;
103 }
104
105 if(ch===')') {
106 state.leaving_expr = true;
107 }
108
109 var match;
110 if(!in_array(state) && (match=stream.match(openers, false))) {
111 state.scopes.push(match);
112 }
113
114 if(!in_array(state) && stream.match(closers, false)) {
115 state.scopes.pop();
116 }
117
118 if(in_array(state)) {
119 if(stream.match(/^end/)) {
120 return 'number';
121 }
122
123 }
124
125 if(stream.match(/^=>/)) {
126 return 'operator';
127 }
128
129
130 // Handle Number Literals
131 if (stream.match(/^[0-9\.]/, false)) {
132 var imMatcher = RegExp(/^im\b/);
133 var floatLiteral = false;
134 // Floats
135 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
136 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
137 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
138 if (floatLiteral) {
139 // Float literals may be "imaginary"
140 stream.match(imMatcher);
141 state.leaving_expr = true;
142 return 'number';
143 }
144 // Integers
145 var intLiteral = false;
146 // Hex
147 if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
148 // Binary
149 if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
150 // Octal
151 if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
152 // Decimal
153 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
154 intLiteral = true;
155 }
156 // Zero by itself with no other piece of number.
157 if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
158 if (intLiteral) {
159 // Integer literals may be "long"
160 stream.match(imMatcher);
161 state.leaving_expr = true;
162 return 'number';
163 }
164 }
165
166 if(stream.match(/^(::)|(<:)/)) {
167 return 'operator';
168 }
169
170 // Handle symbols
171 if(!leaving_expr && stream.match(symbol)) {
172 return 'string';
173 }
174
175 // Handle operators and Delimiters
176 if (stream.match(operators)) {
177 return 'operator';
178 }
179
180
181 // Handle Strings
182 if (stream.match(stringPrefixes)) {
183 state.tokenize = tokenStringFactory(stream.current());
184 return state.tokenize(stream, state);
185 }
186
187 if (stream.match(macro)) {
188 return 'meta';
189 }
190
191
192 if (stream.match(delimiters)) {
193 return null;
194 }
195
196 if (stream.match(keywords)) {
197 return 'keyword';
198 }
199
200 if (stream.match(builtins)) {
201 return 'builtin';
202 }
203
204
205 if (stream.match(identifiers)) {
206 state.leaving_expr=true;
207 return 'variable';
208 }
209 // Handle non-detected items
210 stream.next();
211 return ERRORCLASS;
212 }
213
214 function tokenStringFactory(delimiter) {
215 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
216 delimiter = delimiter.substr(1);
217 }
218 var singleline = delimiter.length == 1;
219 var OUTCLASS = 'string';
220
221 function tokenString(stream, state) {
222 while (!stream.eol()) {
223 stream.eatWhile(/[^'"\\]/);
224 if (stream.eat('\\')) {
225 stream.next();
226 if (singleline && stream.eol()) {
227 return OUTCLASS;
228 }
229 } else if (stream.match(delimiter)) {
230 state.tokenize = tokenBase;
231 return OUTCLASS;
232 } else {
233 stream.eat(/['"]/);
234 }
235 }
236 if (singleline) {
237 if (parserConf.singleLineStringErrors) {
238 return ERRORCLASS;
239 } else {
240 state.tokenize = tokenBase;
241 }
242 }
243 return OUTCLASS;
244 }
245 tokenString.isString = true;
246 return tokenString;
247 }
248
249 function tokenLexer(stream, state) {
250 indentInfo = null;
251 var style = state.tokenize(stream, state);
252 var current = stream.current();
253
254 // Handle '.' connected identifiers
255 if (current === '.') {
256 style = stream.match(identifiers, false) ? null : ERRORCLASS;
257 if (style === null && state.lastStyle === 'meta') {
258 // Apply 'meta' style to '.' connected identifiers when
259 // appropriate.
260 style = 'meta';
261 }
262 return style;
263 }
264
265 return style;
266 }
267
268 var external = {
269 startState: function() {
270 return {
271 tokenize: tokenBase,
272 scopes: [],
273 leaving_expr: false
274 };
275 },
276
277 token: function(stream, state) {
278 var style = tokenLexer(stream, state);
279 state.lastStyle = style;
280 return style;
281 },
282
283 indent: function(state, textAfter) {
284 var delta = 0;
285 if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
286 delta = -1;
287 }
288 return (state.scopes.length + delta) * 4;
289 },
290
291 lineComment: "#",
292 fold: "indent",
293 electricChars: "edlsifyh]}"
294 };
295 return external;
296 });
297
298
299 CodeMirror.defineMIME("text/x-julia", "julia");
300
301 });
@@ -1,280 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("kotlin", function (config, parserConfig) {
15 function words(str) {
16 var obj = {}, words = str.split(" ");
17 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 return obj;
19 }
20
21 var multiLineStrings = parserConfig.multiLineStrings;
22
23 var keywords = words(
24 "package continue return object while break class data trait throw super" +
25 " when type this else This try val var fun for is in if do as true false null get set");
26 var softKeywords = words("import" +
27 " where by get set abstract enum open annotation override private public internal" +
28 " protected catch out vararg inline finally final ref");
29 var blockKeywords = words("catch class do else finally for if where try while enum");
30 var atoms = words("null true false this");
31
32 var curPunc;
33
34 function tokenBase(stream, state) {
35 var ch = stream.next();
36 if (ch == '"' || ch == "'") {
37 return startString(ch, stream, state);
38 }
39 // Wildcard import w/o trailing semicolon (import smth.*)
40 if (ch == "." && stream.eat("*")) {
41 return "word";
42 }
43 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
44 curPunc = ch;
45 return null;
46 }
47 if (/\d/.test(ch)) {
48 if (stream.eat(/eE/)) {
49 stream.eat(/\+\-/);
50 stream.eatWhile(/\d/);
51 }
52 return "number";
53 }
54 if (ch == "/") {
55 if (stream.eat("*")) {
56 state.tokenize.push(tokenComment);
57 return tokenComment(stream, state);
58 }
59 if (stream.eat("/")) {
60 stream.skipToEnd();
61 return "comment";
62 }
63 if (expectExpression(state.lastToken)) {
64 return startString(ch, stream, state);
65 }
66 }
67 // Commented
68 if (ch == "-" && stream.eat(">")) {
69 curPunc = "->";
70 return null;
71 }
72 if (/[\-+*&%=<>!?|\/~]/.test(ch)) {
73 stream.eatWhile(/[\-+*&%=<>|~]/);
74 return "operator";
75 }
76 stream.eatWhile(/[\w\$_]/);
77
78 var cur = stream.current();
79 if (atoms.propertyIsEnumerable(cur)) {
80 return "atom";
81 }
82 if (softKeywords.propertyIsEnumerable(cur)) {
83 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
84 return "softKeyword";
85 }
86
87 if (keywords.propertyIsEnumerable(cur)) {
88 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
89 return "keyword";
90 }
91 return "word";
92 }
93
94 tokenBase.isBase = true;
95
96 function startString(quote, stream, state) {
97 var tripleQuoted = false;
98 if (quote != "/" && stream.eat(quote)) {
99 if (stream.eat(quote)) tripleQuoted = true;
100 else return "string";
101 }
102 function t(stream, state) {
103 var escaped = false, next, end = !tripleQuoted;
104
105 while ((next = stream.next()) != null) {
106 if (next == quote && !escaped) {
107 if (!tripleQuoted) {
108 break;
109 }
110 if (stream.match(quote + quote)) {
111 end = true;
112 break;
113 }
114 }
115
116 if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
117 state.tokenize.push(tokenBaseUntilBrace());
118 return "string";
119 }
120
121 if (next == "$" && !escaped && !stream.eat(" ")) {
122 state.tokenize.push(tokenBaseUntilSpace());
123 return "string";
124 }
125 escaped = !escaped && next == "\\";
126 }
127 if (multiLineStrings)
128 state.tokenize.push(t);
129 if (end) state.tokenize.pop();
130 return "string";
131 }
132
133 state.tokenize.push(t);
134 return t(stream, state);
135 }
136
137 function tokenBaseUntilBrace() {
138 var depth = 1;
139
140 function t(stream, state) {
141 if (stream.peek() == "}") {
142 depth--;
143 if (depth == 0) {
144 state.tokenize.pop();
145 return state.tokenize[state.tokenize.length - 1](stream, state);
146 }
147 } else if (stream.peek() == "{") {
148 depth++;
149 }
150 return tokenBase(stream, state);
151 }
152
153 t.isBase = true;
154 return t;
155 }
156
157 function tokenBaseUntilSpace() {
158 function t(stream, state) {
159 if (stream.eat(/[\w]/)) {
160 var isWord = stream.eatWhile(/[\w]/);
161 if (isWord) {
162 state.tokenize.pop();
163 return "word";
164 }
165 }
166 state.tokenize.pop();
167 return "string";
168 }
169
170 t.isBase = true;
171 return t;
172 }
173
174 function tokenComment(stream, state) {
175 var maybeEnd = false, ch;
176 while (ch = stream.next()) {
177 if (ch == "/" && maybeEnd) {
178 state.tokenize.pop();
179 break;
180 }
181 maybeEnd = (ch == "*");
182 }
183 return "comment";
184 }
185
186 function expectExpression(last) {
187 return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
188 last == "newstatement" || last == "keyword" || last == "proplabel";
189 }
190
191 function Context(indented, column, type, align, prev) {
192 this.indented = indented;
193 this.column = column;
194 this.type = type;
195 this.align = align;
196 this.prev = prev;
197 }
198
199 function pushContext(state, col, type) {
200 return state.context = new Context(state.indented, col, type, null, state.context);
201 }
202
203 function popContext(state) {
204 var t = state.context.type;
205 if (t == ")" || t == "]" || t == "}")
206 state.indented = state.context.indented;
207 return state.context = state.context.prev;
208 }
209
210 // Interface
211
212 return {
213 startState: function (basecolumn) {
214 return {
215 tokenize: [tokenBase],
216 context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
217 indented: 0,
218 startOfLine: true,
219 lastToken: null
220 };
221 },
222
223 token: function (stream, state) {
224 var ctx = state.context;
225 if (stream.sol()) {
226 if (ctx.align == null) ctx.align = false;
227 state.indented = stream.indentation();
228 state.startOfLine = true;
229 // Automatic semicolon insertion
230 if (ctx.type == "statement" && !expectExpression(state.lastToken)) {
231 popContext(state);
232 ctx = state.context;
233 }
234 }
235 if (stream.eatSpace()) return null;
236 curPunc = null;
237 var style = state.tokenize[state.tokenize.length - 1](stream, state);
238 if (style == "comment") return style;
239 if (ctx.align == null) ctx.align = true;
240 if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
241 // Handle indentation for {x -> \n ... }
242 else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
243 popContext(state);
244 state.context.align = false;
245 }
246 else if (curPunc == "{") pushContext(state, stream.column(), "}");
247 else if (curPunc == "[") pushContext(state, stream.column(), "]");
248 else if (curPunc == "(") pushContext(state, stream.column(), ")");
249 else if (curPunc == "}") {
250 while (ctx.type == "statement") ctx = popContext(state);
251 if (ctx.type == "}") ctx = popContext(state);
252 while (ctx.type == "statement") ctx = popContext(state);
253 }
254 else if (curPunc == ctx.type) popContext(state);
255 else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
256 pushContext(state, stream.column(), "statement");
257 state.startOfLine = false;
258 state.lastToken = curPunc || style;
259 return style;
260 },
261
262 indent: function (state, textAfter) {
263 if (!state.tokenize[state.tokenize.length - 1].isBase) return 0;
264 var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
265 if (ctx.type == "statement" && !expectExpression(state.lastToken)) ctx = ctx.prev;
266 var closing = firstChar == ctx.type;
267 if (ctx.type == "statement") {
268 return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
269 }
270 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
271 else return ctx.indented + (closing ? 0 : config.indentUnit);
272 },
273
274 electricChars: "{}"
275 };
276 });
277
278 CodeMirror.defineMIME("text/x-kotlin", "kotlin");
279
280 });
@@ -1,280 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Link to the project's GitHub page:
6 * https://github.com/duralog/CodeMirror
7 */
8
9 (function(mod) {
10 if (typeof exports == "object" && typeof module == "object") // CommonJS
11 mod(require("../../lib/codemirror"));
12 else if (typeof define == "function" && define.amd) // AMD
13 define(["../../lib/codemirror"], mod);
14 else // Plain browser env
15 mod(CodeMirror);
16 })(function(CodeMirror) {
17 "use strict";
18
19 CodeMirror.defineMode('livescript', function(){
20 var tokenBase = function(stream, state) {
21 var next_rule = state.next || "start";
22 if (next_rule) {
23 state.next = state.next;
24 var nr = Rules[next_rule];
25 if (nr.splice) {
26 for (var i$ = 0; i$ < nr.length; ++i$) {
27 var r = nr[i$], m;
28 if (r.regex && (m = stream.match(r.regex))) {
29 state.next = r.next || state.next;
30 return r.token;
31 }
32 }
33 stream.next();
34 return 'error';
35 }
36 if (stream.match(r = Rules[next_rule])) {
37 if (r.regex && stream.match(r.regex)) {
38 state.next = r.next;
39 return r.token;
40 } else {
41 stream.next();
42 return 'error';
43 }
44 }
45 }
46 stream.next();
47 return 'error';
48 };
49 var external = {
50 startState: function(){
51 return {
52 next: 'start',
53 lastToken: null
54 };
55 },
56 token: function(stream, state){
57 while (stream.pos == stream.start)
58 var style = tokenBase(stream, state);
59 state.lastToken = {
60 style: style,
61 indent: stream.indentation(),
62 content: stream.current()
63 };
64 return style.replace(/\./g, ' ');
65 },
66 indent: function(state){
67 var indentation = state.lastToken.indent;
68 if (state.lastToken.content.match(indenter)) {
69 indentation += 2;
70 }
71 return indentation;
72 }
73 };
74 return external;
75 });
76
77 var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
78 var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
79 var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
80 var stringfill = {
81 token: 'string',
82 regex: '.+'
83 };
84 var Rules = {
85 start: [
86 {
87 token: 'comment.doc',
88 regex: '/\\*',
89 next: 'comment'
90 }, {
91 token: 'comment',
92 regex: '#.*'
93 }, {
94 token: 'keyword',
95 regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
96 }, {
97 token: 'constant.language',
98 regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
99 }, {
100 token: 'invalid.illegal',
101 regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
102 }, {
103 token: 'language.support.class',
104 regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
105 }, {
106 token: 'language.support.function',
107 regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
108 }, {
109 token: 'variable.language',
110 regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
111 }, {
112 token: 'identifier',
113 regex: identifier + '\\s*:(?![:=])'
114 }, {
115 token: 'variable',
116 regex: identifier
117 }, {
118 token: 'keyword.operator',
119 regex: '(?:\\.{3}|\\s+\\?)'
120 }, {
121 token: 'keyword.variable',
122 regex: '(?:@+|::|\\.\\.)',
123 next: 'key'
124 }, {
125 token: 'keyword.operator',
126 regex: '\\.\\s*',
127 next: 'key'
128 }, {
129 token: 'string',
130 regex: '\\\\\\S[^\\s,;)}\\]]*'
131 }, {
132 token: 'string.doc',
133 regex: '\'\'\'',
134 next: 'qdoc'
135 }, {
136 token: 'string.doc',
137 regex: '"""',
138 next: 'qqdoc'
139 }, {
140 token: 'string',
141 regex: '\'',
142 next: 'qstring'
143 }, {
144 token: 'string',
145 regex: '"',
146 next: 'qqstring'
147 }, {
148 token: 'string',
149 regex: '`',
150 next: 'js'
151 }, {
152 token: 'string',
153 regex: '<\\[',
154 next: 'words'
155 }, {
156 token: 'string.regex',
157 regex: '//',
158 next: 'heregex'
159 }, {
160 token: 'string.regex',
161 regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
162 next: 'key'
163 }, {
164 token: 'constant.numeric',
165 regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
166 }, {
167 token: 'lparen',
168 regex: '[({[]'
169 }, {
170 token: 'rparen',
171 regex: '[)}\\]]',
172 next: 'key'
173 }, {
174 token: 'keyword.operator',
175 regex: '\\S+'
176 }, {
177 token: 'text',
178 regex: '\\s+'
179 }
180 ],
181 heregex: [
182 {
183 token: 'string.regex',
184 regex: '.*?//[gimy$?]{0,4}',
185 next: 'start'
186 }, {
187 token: 'string.regex',
188 regex: '\\s*#{'
189 }, {
190 token: 'comment.regex',
191 regex: '\\s+(?:#.*)?'
192 }, {
193 token: 'string.regex',
194 regex: '\\S+'
195 }
196 ],
197 key: [
198 {
199 token: 'keyword.operator',
200 regex: '[.?@!]+'
201 }, {
202 token: 'identifier',
203 regex: identifier,
204 next: 'start'
205 }, {
206 token: 'text',
207 regex: '',
208 next: 'start'
209 }
210 ],
211 comment: [
212 {
213 token: 'comment.doc',
214 regex: '.*?\\*/',
215 next: 'start'
216 }, {
217 token: 'comment.doc',
218 regex: '.+'
219 }
220 ],
221 qdoc: [
222 {
223 token: 'string',
224 regex: ".*?'''",
225 next: 'key'
226 }, stringfill
227 ],
228 qqdoc: [
229 {
230 token: 'string',
231 regex: '.*?"""',
232 next: 'key'
233 }, stringfill
234 ],
235 qstring: [
236 {
237 token: 'string',
238 regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
239 next: 'key'
240 }, stringfill
241 ],
242 qqstring: [
243 {
244 token: 'string',
245 regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
246 next: 'key'
247 }, stringfill
248 ],
249 js: [
250 {
251 token: 'string',
252 regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
253 next: 'key'
254 }, stringfill
255 ],
256 words: [
257 {
258 token: 'string',
259 regex: '.*?\\]>',
260 next: 'key'
261 }, stringfill
262 ]
263 };
264 for (var idx in Rules) {
265 var r = Rules[idx];
266 if (r.splice) {
267 for (var i = 0, len = r.length; i < len; ++i) {
268 var rr = r[i];
269 if (typeof rr.regex === 'string') {
270 Rules[idx][i].regex = new RegExp('^' + rr.regex);
271 }
272 }
273 } else if (typeof rr.regex === 'string') {
274 Rules[idx].regex = new RegExp('^' + r.regex);
275 }
276 }
277
278 CodeMirror.defineMIME('text/x-livescript', 'livescript');
279
280 });
@@ -1,159 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's
5 // CodeMirror 1 mode.
6 // highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting
7
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15 })(function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("lua", function(config, parserConfig) {
19 var indentUnit = config.indentUnit;
20
21 function prefixRE(words) {
22 return new RegExp("^(?:" + words.join("|") + ")", "i");
23 }
24 function wordRE(words) {
25 return new RegExp("^(?:" + words.join("|") + ")$", "i");
26 }
27 var specials = wordRE(parserConfig.specials || []);
28
29 // long list of standard functions from lua manual
30 var builtins = wordRE([
31 "_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load",
32 "loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require",
33 "select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall",
34
35 "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield",
36
37 "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable",
38 "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable",
39 "debug.setupvalue","debug.traceback",
40
41 "close","flush","lines","read","seek","setvbuf","write",
42
43 "io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin",
44 "io.stdout","io.tmpfile","io.type","io.write",
45
46 "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg",
47 "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max",
48 "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh",
49 "math.sqrt","math.tan","math.tanh",
50
51 "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale",
52 "os.time","os.tmpname",
53
54 "package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload",
55 "package.seeall",
56
57 "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub",
58 "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper",
59
60 "table.concat","table.insert","table.maxn","table.remove","table.sort"
61 ]);
62 var keywords = wordRE(["and","break","elseif","false","nil","not","or","return",
63 "true","function", "end", "if", "then", "else", "do",
64 "while", "repeat", "until", "for", "in", "local" ]);
65
66 var indentTokens = wordRE(["function", "if","repeat","do", "\\(", "{"]);
67 var dedentTokens = wordRE(["end", "until", "\\)", "}"]);
68 var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]);
69
70 function readBracket(stream) {
71 var level = 0;
72 while (stream.eat("=")) ++level;
73 stream.eat("[");
74 return level;
75 }
76
77 function normal(stream, state) {
78 var ch = stream.next();
79 if (ch == "-" && stream.eat("-")) {
80 if (stream.eat("[") && stream.eat("["))
81 return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state);
82 stream.skipToEnd();
83 return "comment";
84 }
85 if (ch == "\"" || ch == "'")
86 return (state.cur = string(ch))(stream, state);
87 if (ch == "[" && /[\[=]/.test(stream.peek()))
88 return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);
89 if (/\d/.test(ch)) {
90 stream.eatWhile(/[\w.%]/);
91 return "number";
92 }
93 if (/[\w_]/.test(ch)) {
94 stream.eatWhile(/[\w\\\-_.]/);
95 return "variable";
96 }
97 return null;
98 }
99
100 function bracketed(level, style) {
101 return function(stream, state) {
102 var curlev = null, ch;
103 while ((ch = stream.next()) != null) {
104 if (curlev == null) {if (ch == "]") curlev = 0;}
105 else if (ch == "=") ++curlev;
106 else if (ch == "]" && curlev == level) { state.cur = normal; break; }
107 else curlev = null;
108 }
109 return style;
110 };
111 }
112
113 function string(quote) {
114 return function(stream, state) {
115 var escaped = false, ch;
116 while ((ch = stream.next()) != null) {
117 if (ch == quote && !escaped) break;
118 escaped = !escaped && ch == "\\";
119 }
120 if (!escaped) state.cur = normal;
121 return "string";
122 };
123 }
124
125 return {
126 startState: function(basecol) {
127 return {basecol: basecol || 0, indentDepth: 0, cur: normal};
128 },
129
130 token: function(stream, state) {
131 if (stream.eatSpace()) return null;
132 var style = state.cur(stream, state);
133 var word = stream.current();
134 if (style == "variable") {
135 if (keywords.test(word)) style = "keyword";
136 else if (builtins.test(word)) style = "builtin";
137 else if (specials.test(word)) style = "variable-2";
138 }
139 if ((style != "comment") && (style != "string")){
140 if (indentTokens.test(word)) ++state.indentDepth;
141 else if (dedentTokens.test(word)) --state.indentDepth;
142 }
143 return style;
144 },
145
146 indent: function(state, textAfter) {
147 var closing = dedentPartial.test(textAfter);
148 return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
149 },
150
151 lineComment: "--",
152 blockCommentStart: "--[[",
153 blockCommentEnd: "]]"
154 };
155 });
156
157 CodeMirror.defineMIME("text/x-lua", "lua");
158
159 });
This diff has been collapsed as it changes many lines, (758 lines changed) Show them Hide them
@@ -1,758 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror", require("../xml/xml")));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../xml/xml"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
15
16 var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
17 var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
18 var aliases = {
19 html: "htmlmixed",
20 js: "javascript",
21 json: "application/json",
22 c: "text/x-csrc",
23 "c++": "text/x-c++src",
24 java: "text/x-java",
25 csharp: "text/x-csharp",
26 "c#": "text/x-csharp",
27 scala: "text/x-scala"
28 };
29
30 var getMode = (function () {
31 var i, modes = {}, mimes = {}, mime;
32
33 var list = [];
34 for (var m in CodeMirror.modes)
35 if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);
36 for (i = 0; i < list.length; i++) {
37 modes[list[i]] = list[i];
38 }
39 var mimesList = [];
40 for (var m in CodeMirror.mimeModes)
41 if (CodeMirror.mimeModes.propertyIsEnumerable(m))
42 mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});
43 for (i = 0; i < mimesList.length; i++) {
44 mime = mimesList[i].mime;
45 mimes[mime] = mimesList[i].mime;
46 }
47
48 for (var a in aliases) {
49 if (aliases[a] in modes || aliases[a] in mimes)
50 modes[a] = aliases[a];
51 }
52
53 return function (lang) {
54 return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
55 };
56 }());
57
58 // Should characters that affect highlighting be highlighted separate?
59 // Does not include characters that will be output (such as `1.` and `-` for lists)
60 if (modeCfg.highlightFormatting === undefined)
61 modeCfg.highlightFormatting = false;
62
63 // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
64 // Excess `>` will emit `error` token.
65 if (modeCfg.maxBlockquoteDepth === undefined)
66 modeCfg.maxBlockquoteDepth = 0;
67
68 // Should underscores in words open/close em/strong?
69 if (modeCfg.underscoresBreakWords === undefined)
70 modeCfg.underscoresBreakWords = true;
71
72 // Turn on fenced code blocks? ("```" to start/end)
73 if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
74
75 // Turn on task lists? ("- [ ] " and "- [x] ")
76 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
77
78 var codeDepth = 0;
79
80 var header = 'header'
81 , code = 'comment'
82 , quote = 'quote'
83 , list1 = 'variable-2'
84 , list2 = 'variable-3'
85 , list3 = 'keyword'
86 , hr = 'hr'
87 , image = 'tag'
88 , formatting = 'formatting'
89 , linkinline = 'link'
90 , linkemail = 'link'
91 , linktext = 'link'
92 , linkhref = 'string'
93 , em = 'em'
94 , strong = 'strong';
95
96 var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
97 , ulRE = /^[*\-+]\s+/
98 , olRE = /^[0-9]+\.\s+/
99 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
100 , atxHeaderRE = /^#+/
101 , setextHeaderRE = /^(?:\={1,}|-{1,})$/
102 , textRE = /^[^#!\[\]*_\\<>` "'(]+/;
103
104 function switchInline(stream, state, f) {
105 state.f = state.inline = f;
106 return f(stream, state);
107 }
108
109 function switchBlock(stream, state, f) {
110 state.f = state.block = f;
111 return f(stream, state);
112 }
113
114
115 // Blocks
116
117 function blankLine(state) {
118 // Reset linkTitle state
119 state.linkTitle = false;
120 // Reset EM state
121 state.em = false;
122 // Reset STRONG state
123 state.strong = false;
124 // Reset state.quote
125 state.quote = 0;
126 if (!htmlFound && state.f == htmlBlock) {
127 state.f = inlineNormal;
128 state.block = blockNormal;
129 }
130 // Reset state.trailingSpace
131 state.trailingSpace = 0;
132 state.trailingSpaceNewLine = false;
133 // Mark this line as blank
134 state.thisLineHasContent = false;
135 return null;
136 }
137
138 function blockNormal(stream, state) {
139
140 var sol = stream.sol();
141
142 var prevLineIsList = (state.list !== false);
143 if (state.list !== false && state.indentationDiff >= 0) { // Continued list
144 if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
145 state.indentation -= state.indentationDiff;
146 }
147 state.list = null;
148 } else if (state.list !== false && state.indentation > 0) {
149 state.list = null;
150 state.listDepth = Math.floor(state.indentation / 4);
151 } else if (state.list !== false) { // No longer a list
152 state.list = false;
153 state.listDepth = 0;
154 }
155
156 var match = null;
157 if (state.indentationDiff >= 4) {
158 state.indentation -= 4;
159 stream.skipToEnd();
160 return code;
161 } else if (stream.eatSpace()) {
162 return null;
163 } else if (match = stream.match(atxHeaderRE)) {
164 state.header = match[0].length <= 6 ? match[0].length : 6;
165 if (modeCfg.highlightFormatting) state.formatting = "header";
166 state.f = state.inline;
167 return getType(state);
168 } else if (state.prevLineHasContent && (match = stream.match(setextHeaderRE))) {
169 state.header = match[0].charAt(0) == '=' ? 1 : 2;
170 if (modeCfg.highlightFormatting) state.formatting = "header";
171 state.f = state.inline;
172 return getType(state);
173 } else if (stream.eat('>')) {
174 state.indentation++;
175 state.quote = sol ? 1 : state.quote + 1;
176 if (modeCfg.highlightFormatting) state.formatting = "quote";
177 stream.eatSpace();
178 return getType(state);
179 } else if (stream.peek() === '[') {
180 return switchInline(stream, state, footnoteLink);
181 } else if (stream.match(hrRE, true)) {
182 return hr;
183 } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
184 var listType = null;
185 if (stream.match(ulRE, true)) {
186 listType = 'ul';
187 } else {
188 stream.match(olRE, true);
189 listType = 'ol';
190 }
191 state.indentation += 4;
192 state.list = true;
193 state.listDepth++;
194 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
195 state.taskList = true;
196 }
197 state.f = state.inline;
198 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
199 return getType(state);
200 } else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
201 // try switching mode
202 state.localMode = getMode(RegExp.$1);
203 if (state.localMode) state.localState = state.localMode.startState();
204 switchBlock(stream, state, local);
205 if (modeCfg.highlightFormatting) state.formatting = "code-block";
206 state.code = true;
207 return getType(state);
208 }
209
210 return switchInline(stream, state, state.inline);
211 }
212
213 function htmlBlock(stream, state) {
214 var style = htmlMode.token(stream, state.htmlState);
215 if ((htmlFound && state.htmlState.tagStart === null && !state.htmlState.context) ||
216 (state.md_inside && stream.current().indexOf(">") > -1)) {
217 state.f = inlineNormal;
218 state.block = blockNormal;
219 state.htmlState = null;
220 }
221 return style;
222 }
223
224 function local(stream, state) {
225 if (stream.sol() && stream.match(/^```/, true)) {
226 state.localMode = state.localState = null;
227 state.f = inlineNormal;
228 state.block = blockNormal;
229 if (modeCfg.highlightFormatting) state.formatting = "code-block";
230 state.code = true;
231 var returnType = getType(state);
232 state.code = false;
233 return returnType;
234 } else if (state.localMode) {
235 return state.localMode.token(stream, state.localState);
236 } else {
237 stream.skipToEnd();
238 return code;
239 }
240 }
241
242 // Inline
243 function getType(state) {
244 var styles = [];
245
246 if (state.formatting) {
247 styles.push(formatting);
248
249 if (typeof state.formatting === "string") state.formatting = [state.formatting];
250
251 for (var i = 0; i < state.formatting.length; i++) {
252 styles.push(formatting + "-" + state.formatting[i]);
253
254 if (state.formatting[i] === "header") {
255 styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
256 }
257
258 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
259 // Add `error` instead if the maximum blockquote nesting depth is passed
260 if (state.formatting[i] === "quote") {
261 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
262 styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
263 } else {
264 styles.push("error");
265 }
266 }
267 }
268 }
269
270 if (state.taskOpen) {
271 styles.push("meta");
272 return styles.length ? styles.join(' ') : null;
273 }
274 if (state.taskClosed) {
275 styles.push("property");
276 return styles.length ? styles.join(' ') : null;
277 }
278
279 if (state.linkHref) {
280 styles.push(linkhref);
281 return styles.length ? styles.join(' ') : null;
282 }
283
284 if (state.strong) { styles.push(strong); }
285 if (state.em) { styles.push(em); }
286
287 if (state.linkText) { styles.push(linktext); }
288
289 if (state.code) { styles.push(code); }
290
291 if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
292
293 if (state.quote) {
294 styles.push(quote);
295
296 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
297 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
298 styles.push(quote + "-" + state.quote);
299 } else {
300 styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
301 }
302 }
303
304 if (state.list !== false) {
305 var listMod = (state.listDepth - 1) % 3;
306 if (!listMod) {
307 styles.push(list1);
308 } else if (listMod === 1) {
309 styles.push(list2);
310 } else {
311 styles.push(list3);
312 }
313 }
314
315 if (state.trailingSpaceNewLine) {
316 styles.push("trailing-space-new-line");
317 } else if (state.trailingSpace) {
318 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
319 }
320
321 return styles.length ? styles.join(' ') : null;
322 }
323
324 function handleText(stream, state) {
325 if (stream.match(textRE, true)) {
326 return getType(state);
327 }
328 return undefined;
329 }
330
331 function inlineNormal(stream, state) {
332 var style = state.text(stream, state);
333 if (typeof style !== 'undefined')
334 return style;
335
336 if (state.list) { // List marker (*, +, -, 1., etc)
337 state.list = null;
338 return getType(state);
339 }
340
341 if (state.taskList) {
342 var taskOpen = stream.match(taskListRE, true)[1] !== "x";
343 if (taskOpen) state.taskOpen = true;
344 else state.taskClosed = true;
345 if (modeCfg.highlightFormatting) state.formatting = "task";
346 state.taskList = false;
347 return getType(state);
348 }
349
350 state.taskOpen = false;
351 state.taskClosed = false;
352
353 if (state.header && stream.match(/^#+$/, true)) {
354 if (modeCfg.highlightFormatting) state.formatting = "header";
355 return getType(state);
356 }
357
358 // Get sol() value now, before character is consumed
359 var sol = stream.sol();
360
361 var ch = stream.next();
362
363 if (ch === '\\') {
364 stream.next();
365 if (modeCfg.highlightFormatting) {
366 var type = getType(state);
367 return type ? type + " formatting-escape" : "formatting-escape";
368 }
369 }
370
371 // Matches link titles present on next line
372 if (state.linkTitle) {
373 state.linkTitle = false;
374 var matchCh = ch;
375 if (ch === '(') {
376 matchCh = ')';
377 }
378 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
379 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
380 if (stream.match(new RegExp(regex), true)) {
381 return linkhref;
382 }
383 }
384
385 // If this block is changed, it may need to be updated in GFM mode
386 if (ch === '`') {
387 var previousFormatting = state.formatting;
388 if (modeCfg.highlightFormatting) state.formatting = "code";
389 var t = getType(state);
390 var before = stream.pos;
391 stream.eatWhile('`');
392 var difference = 1 + stream.pos - before;
393 if (!state.code) {
394 codeDepth = difference;
395 state.code = true;
396 return getType(state);
397 } else {
398 if (difference === codeDepth) { // Must be exact
399 state.code = false;
400 return t;
401 }
402 state.formatting = previousFormatting;
403 return getType(state);
404 }
405 } else if (state.code) {
406 return getType(state);
407 }
408
409 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
410 stream.match(/\[[^\]]*\]/);
411 state.inline = state.f = linkHref;
412 return image;
413 }
414
415 if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
416 state.linkText = true;
417 if (modeCfg.highlightFormatting) state.formatting = "link";
418 return getType(state);
419 }
420
421 if (ch === ']' && state.linkText) {
422 if (modeCfg.highlightFormatting) state.formatting = "link";
423 var type = getType(state);
424 state.linkText = false;
425 state.inline = state.f = linkHref;
426 return type;
427 }
428
429 if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
430 state.f = state.inline = linkInline;
431 if (modeCfg.highlightFormatting) state.formatting = "link";
432 var type = getType(state);
433 if (type){
434 type += " ";
435 } else {
436 type = "";
437 }
438 return type + linkinline;
439 }
440
441 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
442 state.f = state.inline = linkInline;
443 if (modeCfg.highlightFormatting) state.formatting = "link";
444 var type = getType(state);
445 if (type){
446 type += " ";
447 } else {
448 type = "";
449 }
450 return type + linkemail;
451 }
452
453 if (ch === '<' && stream.match(/^\w/, false)) {
454 if (stream.string.indexOf(">") != -1) {
455 var atts = stream.string.substring(1,stream.string.indexOf(">"));
456 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
457 state.md_inside = true;
458 }
459 }
460 stream.backUp(1);
461 state.htmlState = CodeMirror.startState(htmlMode);
462 return switchBlock(stream, state, htmlBlock);
463 }
464
465 if (ch === '<' && stream.match(/^\/\w*?>/)) {
466 state.md_inside = false;
467 return "tag";
468 }
469
470 var ignoreUnderscore = false;
471 if (!modeCfg.underscoresBreakWords) {
472 if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
473 var prevPos = stream.pos - 2;
474 if (prevPos >= 0) {
475 var prevCh = stream.string.charAt(prevPos);
476 if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
477 ignoreUnderscore = true;
478 }
479 }
480 }
481 }
482 if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
483 if (sol && stream.peek() === ' ') {
484 // Do nothing, surrounded by newline and space
485 } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
486 if (modeCfg.highlightFormatting) state.formatting = "strong";
487 var t = getType(state);
488 state.strong = false;
489 return t;
490 } else if (!state.strong && stream.eat(ch)) { // Add STRONG
491 state.strong = ch;
492 if (modeCfg.highlightFormatting) state.formatting = "strong";
493 return getType(state);
494 } else if (state.em === ch) { // Remove EM
495 if (modeCfg.highlightFormatting) state.formatting = "em";
496 var t = getType(state);
497 state.em = false;
498 return t;
499 } else if (!state.em) { // Add EM
500 state.em = ch;
501 if (modeCfg.highlightFormatting) state.formatting = "em";
502 return getType(state);
503 }
504 } else if (ch === ' ') {
505 if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
506 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
507 return getType(state);
508 } else { // Not surrounded by spaces, back up pointer
509 stream.backUp(1);
510 }
511 }
512 }
513
514 if (ch === ' ') {
515 if (stream.match(/ +$/, false)) {
516 state.trailingSpace++;
517 } else if (state.trailingSpace) {
518 state.trailingSpaceNewLine = true;
519 }
520 }
521
522 return getType(state);
523 }
524
525 function linkInline(stream, state) {
526 var ch = stream.next();
527
528 if (ch === ">") {
529 state.f = state.inline = inlineNormal;
530 if (modeCfg.highlightFormatting) state.formatting = "link";
531 var type = getType(state);
532 if (type){
533 type += " ";
534 } else {
535 type = "";
536 }
537 return type + linkinline;
538 }
539
540 stream.match(/^[^>]+/, true);
541
542 return linkinline;
543 }
544
545 function linkHref(stream, state) {
546 // Check if space, and return NULL if so (to avoid marking the space)
547 if(stream.eatSpace()){
548 return null;
549 }
550 var ch = stream.next();
551 if (ch === '(' || ch === '[') {
552 state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
553 if (modeCfg.highlightFormatting) state.formatting = "link-string";
554 state.linkHref = true;
555 return getType(state);
556 }
557 return 'error';
558 }
559
560 function getLinkHrefInside(endChar) {
561 return function(stream, state) {
562 var ch = stream.next();
563
564 if (ch === endChar) {
565 state.f = state.inline = inlineNormal;
566 if (modeCfg.highlightFormatting) state.formatting = "link-string";
567 var returnState = getType(state);
568 state.linkHref = false;
569 return returnState;
570 }
571
572 if (stream.match(inlineRE(endChar), true)) {
573 stream.backUp(1);
574 }
575
576 state.linkHref = true;
577 return getType(state);
578 };
579 }
580
581 function footnoteLink(stream, state) {
582 if (stream.match(/^[^\]]*\]:/, false)) {
583 state.f = footnoteLinkInside;
584 stream.next(); // Consume [
585 if (modeCfg.highlightFormatting) state.formatting = "link";
586 state.linkText = true;
587 return getType(state);
588 }
589 return switchInline(stream, state, inlineNormal);
590 }
591
592 function footnoteLinkInside(stream, state) {
593 if (stream.match(/^\]:/, true)) {
594 state.f = state.inline = footnoteUrl;
595 if (modeCfg.highlightFormatting) state.formatting = "link";
596 var returnType = getType(state);
597 state.linkText = false;
598 return returnType;
599 }
600
601 stream.match(/^[^\]]+/, true);
602
603 return linktext;
604 }
605
606 function footnoteUrl(stream, state) {
607 // Check if space, and return NULL if so (to avoid marking the space)
608 if(stream.eatSpace()){
609 return null;
610 }
611 // Match URL
612 stream.match(/^[^\s]+/, true);
613 // Check for link title
614 if (stream.peek() === undefined) { // End of line, set flag to check next line
615 state.linkTitle = true;
616 } else { // More content on line, check if link title
617 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
618 }
619 state.f = state.inline = inlineNormal;
620 return linkhref;
621 }
622
623 var savedInlineRE = [];
624 function inlineRE(endChar) {
625 if (!savedInlineRE[endChar]) {
626 // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
627 endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
628 // Match any non-endChar, escaped character, as well as the closing
629 // endChar.
630 savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
631 }
632 return savedInlineRE[endChar];
633 }
634
635 var mode = {
636 startState: function() {
637 return {
638 f: blockNormal,
639
640 prevLineHasContent: false,
641 thisLineHasContent: false,
642
643 block: blockNormal,
644 htmlState: null,
645 indentation: 0,
646
647 inline: inlineNormal,
648 text: handleText,
649
650 formatting: false,
651 linkText: false,
652 linkHref: false,
653 linkTitle: false,
654 em: false,
655 strong: false,
656 header: 0,
657 taskList: false,
658 list: false,
659 listDepth: 0,
660 quote: 0,
661 trailingSpace: 0,
662 trailingSpaceNewLine: false
663 };
664 },
665
666 copyState: function(s) {
667 return {
668 f: s.f,
669
670 prevLineHasContent: s.prevLineHasContent,
671 thisLineHasContent: s.thisLineHasContent,
672
673 block: s.block,
674 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
675 indentation: s.indentation,
676
677 localMode: s.localMode,
678 localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
679
680 inline: s.inline,
681 text: s.text,
682 formatting: false,
683 linkTitle: s.linkTitle,
684 em: s.em,
685 strong: s.strong,
686 header: s.header,
687 taskList: s.taskList,
688 list: s.list,
689 listDepth: s.listDepth,
690 quote: s.quote,
691 trailingSpace: s.trailingSpace,
692 trailingSpaceNewLine: s.trailingSpaceNewLine,
693 md_inside: s.md_inside
694 };
695 },
696
697 token: function(stream, state) {
698
699 // Reset state.formatting
700 state.formatting = false;
701
702 if (stream.sol()) {
703 var forceBlankLine = !!state.header;
704
705 // Reset state.header
706 state.header = 0;
707
708 if (stream.match(/^\s*$/, true) || forceBlankLine) {
709 state.prevLineHasContent = false;
710 blankLine(state);
711 return forceBlankLine ? this.token(stream, state) : null;
712 } else {
713 state.prevLineHasContent = state.thisLineHasContent;
714 state.thisLineHasContent = true;
715 }
716
717 // Reset state.taskList
718 state.taskList = false;
719
720 // Reset state.code
721 state.code = false;
722
723 // Reset state.trailingSpace
724 state.trailingSpace = 0;
725 state.trailingSpaceNewLine = false;
726
727 state.f = state.block;
728 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
729 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
730 if (difference > 4) difference = 4;
731 var adjustedIndentation = state.indentation + difference;
732 state.indentationDiff = adjustedIndentation - state.indentation;
733 state.indentation = adjustedIndentation;
734 if (indentation > 0) return null;
735 }
736 var result = state.f(stream, state);
737 if (stream.start == stream.pos) return this.token(stream, state);
738 else return result;
739 },
740
741 innerMode: function(state) {
742 if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
743 if (state.localState) return {state: state.localState, mode: state.localMode};
744 return {state: state, mode: mode};
745 },
746
747 blankLine: blankLine,
748
749 getType: getType,
750
751 fold: "markdown"
752 };
753 return mode;
754 }, "xml");
755
756 CodeMirror.defineMIME("text/x-markdown", "markdown");
757
758 });
@@ -1,144 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.modeInfo = [
15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
16 {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk"},
17 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
18 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "hpp", "h++"]},
19 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
20 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"]},
21 {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
22 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"]},
23 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"]},
24 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher"},
25 {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
26 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
27 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
28 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
29 {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
30 {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
31 {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
32 {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
33 {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
34 {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
35 {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
36 {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
37 {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"]},
38 {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
39 {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
40 {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm"},
41 {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
42 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
43 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
44 {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
45 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
46 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
47 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"]},
48 {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"]},
49 {name: "HTTP", mime: "message/http", mode: "http"},
50 {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]},
51 {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
52 {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"]},
53 {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
54 mode: "javascript", ext: ["js"]},
55 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"]},
56 {name: "JSON-LD", mime: "application/ld+json", mode: "javascript"},
57 {name: "Jinja2", mime: "null", mode: "jinja2"},
58 {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
59 {name: "Kotlin", mime: "text/x-kotlin", mode: "kotlin", ext: ["kt"]},
60 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
61 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"]},
62 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
63 {name: "Markdown (GitHub-flavour)", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
64 {name: "mIRC", mime: "text/mirc", mode: "mirc"},
65 {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
66 {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
67 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
68 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
69 {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx"},
70 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
71 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
72 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
73 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
74 {name: "PEG.js", mime: "null", mode: "pegjs"},
75 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
76 {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
77 {name: "Pig", mime: "text/x-pig", mode: "pig"},
78 {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
79 {name: "PLSQL", mime: "text/x-plsql", mode: "sql"},
80 {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"]},
81 {name: "Python", mime: "text/x-python", mode: "python", ext: ["py", "pyw"]},
82 {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
83 {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
84 {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"]},
85 {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"]},
86 {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"]},
87 {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
88 {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
89 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
90 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
91 {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
92 {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"]},
93 {name: "Sieve", mime: "application/sieve", mode: "sieve"},
94 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim"},
95 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
96 {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
97 {name: "SmartyMixed", mime: "text/x-smarty", mode: "smartymixed"},
98 {name: "Solr", mime: "text/x-solr", mode: "solr"},
99 {name: "SPARQL", mime: "application/x-sparql-query", mode: "sparql", ext: ["sparql"]},
100 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
101 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
102 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
103 {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"]},
104 {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
105 {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
106 {name: "Textile", mime: "text/x-textile", mode: "textile"},
107 {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
108 {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
109 {name: "TOML", mime: "text/x-toml", mode: "toml"},
110 {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
111 {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
112 {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"]},
113 {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
114 {name: "VBScript", mime: "text/vbscript", mode: "vbscript"},
115 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
116 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
117 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"]},
118 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
119 {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml"]},
120 {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}
121 ];
122 // Ensure all modes have a mime property for backwards compatibility
123 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
124 var info = CodeMirror.modeInfo[i];
125 if (info.mimes) info.mime = info.mimes[0];
126 }
127
128 CodeMirror.findModeByMIME = function(mime) {
129 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
130 var info = CodeMirror.modeInfo[i];
131 if (info.mime == mime) return info;
132 if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
133 if (info.mimes[j] == mime) return info;
134 }
135 };
136
137 CodeMirror.findModeByExtension = function(ext) {
138 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
139 var info = CodeMirror.modeInfo[i];
140 if (info.ext) for (var j = 0; j < info.ext.length; j++)
141 if (info.ext[j] == ext) return info;
142 }
143 };
144 });
@@ -1,193 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 //mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMIME("text/mirc", "mirc");
17 CodeMirror.defineMode("mirc", function() {
18 function parseWords(str) {
19 var obj = {}, words = str.split(" ");
20 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
21 return obj;
22 }
23 var specials = parseWords("$! $$ $& $? $+ $abook $abs $active $activecid " +
24 "$activewid $address $addtok $agent $agentname $agentstat $agentver " +
25 "$alias $and $anick $ansi2mirc $aop $appactive $appstate $asc $asctime " +
26 "$asin $atan $avoice $away $awaymsg $awaytime $banmask $base $bfind " +
27 "$binoff $biton $bnick $bvar $bytes $calc $cb $cd $ceil $chan $chanmodes " +
28 "$chantypes $chat $chr $cid $clevel $click $cmdbox $cmdline $cnick $color " +
29 "$com $comcall $comchan $comerr $compact $compress $comval $cos $count " +
30 "$cr $crc $creq $crlf $ctime $ctimer $ctrlenter $date $day $daylight " +
31 "$dbuh $dbuw $dccignore $dccport $dde $ddename $debug $decode $decompress " +
32 "$deltok $devent $dialog $did $didreg $didtok $didwm $disk $dlevel $dll " +
33 "$dllcall $dname $dns $duration $ebeeps $editbox $emailaddr $encode $error " +
34 "$eval $event $exist $feof $ferr $fgetc $file $filename $filtered $finddir " +
35 "$finddirn $findfile $findfilen $findtok $fline $floor $fopen $fread $fserve " +
36 "$fulladdress $fulldate $fullname $fullscreen $get $getdir $getdot $gettok $gmt " +
37 "$group $halted $hash $height $hfind $hget $highlight $hnick $hotline " +
38 "$hotlinepos $ial $ialchan $ibl $idle $iel $ifmatch $ignore $iif $iil " +
39 "$inelipse $ini $inmidi $inpaste $inpoly $input $inrect $inroundrect " +
40 "$insong $instok $int $inwave $ip $isalias $isbit $isdde $isdir $isfile " +
41 "$isid $islower $istok $isupper $keychar $keyrpt $keyval $knick $lactive " +
42 "$lactivecid $lactivewid $left $len $level $lf $line $lines $link $lock " +
43 "$lock $locked $log $logstamp $logstampfmt $longfn $longip $lower $ltimer " +
44 "$maddress $mask $matchkey $matchtok $md5 $me $menu $menubar $menucontext " +
45 "$menutype $mid $middir $mircdir $mircexe $mircini $mklogfn $mnick $mode " +
46 "$modefirst $modelast $modespl $mouse $msfile $network $newnick $nick $nofile " +
47 "$nopath $noqt $not $notags $notify $null $numeric $numok $oline $onpoly " +
48 "$opnick $or $ord $os $passivedcc $pic $play $pnick $port $portable $portfree " +
49 "$pos $prefix $prop $protect $puttok $qt $query $rand $r $rawmsg $read $readomo " +
50 "$readn $regex $regml $regsub $regsubex $remove $remtok $replace $replacex " +
51 "$reptok $result $rgb $right $round $scid $scon $script $scriptdir $scriptline " +
52 "$sdir $send $server $serverip $sfile $sha1 $shortfn $show $signal $sin " +
53 "$site $sline $snick $snicks $snotify $sock $sockbr $sockerr $sockname " +
54 "$sorttok $sound $sqrt $ssl $sreq $sslready $status $strip $str $stripped " +
55 "$syle $submenu $switchbar $tan $target $ticks $time $timer $timestamp " +
56 "$timestampfmt $timezone $tip $titlebar $toolbar $treebar $trust $ulevel " +
57 "$ulist $upper $uptime $url $usermode $v1 $v2 $var $vcmd $vcmdstat $vcmdver " +
58 "$version $vnick $vol $wid $width $wildsite $wildtok $window $wrap $xor");
59 var keywords = parseWords("abook ajinvite alias aline ame amsg anick aop auser autojoin avoice " +
60 "away background ban bcopy beep bread break breplace bset btrunc bunset bwrite " +
61 "channel clear clearall cline clipboard close cnick color comclose comopen " +
62 "comreg continue copy creq ctcpreply ctcps dcc dccserver dde ddeserver " +
63 "debug dec describe dialog did didtok disable disconnect dlevel dline dll " +
64 "dns dqwindow drawcopy drawdot drawfill drawline drawpic drawrect drawreplace " +
65 "drawrot drawsave drawscroll drawtext ebeeps echo editbox emailaddr enable " +
66 "events exit fclose filter findtext finger firewall flash flist flood flush " +
67 "flushini font fopen fseek fsend fserve fullname fwrite ghide gload gmove " +
68 "gopts goto gplay gpoint gqreq groups gshow gsize gstop gtalk gunload hadd " +
69 "halt haltdef hdec hdel help hfree hinc hload hmake hop hsave ial ialclear " +
70 "ialmark identd if ignore iline inc invite iuser join kick linesep links list " +
71 "load loadbuf localinfo log mdi me menubar mkdir mnick mode msg nick noop notice " +
72 "notify omsg onotice part partall pdcc perform play playctrl pop protect pvoice " +
73 "qme qmsg query queryn quit raw reload remini remote remove rename renwin " +
74 "reseterror resetidle return rlevel rline rmdir run ruser save savebuf saveini " +
75 "say scid scon server set showmirc signam sline sockaccept sockclose socklist " +
76 "socklisten sockmark sockopen sockpause sockread sockrename sockudp sockwrite " +
77 "sound speak splay sreq strip switchbar timer timestamp titlebar tnick tokenize " +
78 "toolbar topic tray treebar ulist unload unset unsetall updatenl url uwho " +
79 "var vcadd vcmd vcrem vol while whois window winhelp write writeint if isalnum " +
80 "isalpha isaop isavoice isban ischan ishop isignore isin isincs isletter islower " +
81 "isnotify isnum ison isop isprotect isreg isupper isvoice iswm iswmcs " +
82 "elseif else goto menu nicklist status title icon size option text edit " +
83 "button check radio box scroll list combo link tab item");
84 var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
85 var isOperatorChar = /[+\-*&%=<>!?^\/\|]/;
86 function chain(stream, state, f) {
87 state.tokenize = f;
88 return f(stream, state);
89 }
90 function tokenBase(stream, state) {
91 var beforeParams = state.beforeParams;
92 state.beforeParams = false;
93 var ch = stream.next();
94 if (/[\[\]{}\(\),\.]/.test(ch)) {
95 if (ch == "(" && beforeParams) state.inParams = true;
96 else if (ch == ")") state.inParams = false;
97 return null;
98 }
99 else if (/\d/.test(ch)) {
100 stream.eatWhile(/[\w\.]/);
101 return "number";
102 }
103 else if (ch == "\\") {
104 stream.eat("\\");
105 stream.eat(/./);
106 return "number";
107 }
108 else if (ch == "/" && stream.eat("*")) {
109 return chain(stream, state, tokenComment);
110 }
111 else if (ch == ";" && stream.match(/ *\( *\(/)) {
112 return chain(stream, state, tokenUnparsed);
113 }
114 else if (ch == ";" && !state.inParams) {
115 stream.skipToEnd();
116 return "comment";
117 }
118 else if (ch == '"') {
119 stream.eat(/"/);
120 return "keyword";
121 }
122 else if (ch == "$") {
123 stream.eatWhile(/[$_a-z0-9A-Z\.:]/);
124 if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) {
125 return "keyword";
126 }
127 else {
128 state.beforeParams = true;
129 return "builtin";
130 }
131 }
132 else if (ch == "%") {
133 stream.eatWhile(/[^,^\s^\(^\)]/);
134 state.beforeParams = true;
135 return "string";
136 }
137 else if (isOperatorChar.test(ch)) {
138 stream.eatWhile(isOperatorChar);
139 return "operator";
140 }
141 else {
142 stream.eatWhile(/[\w\$_{}]/);
143 var word = stream.current().toLowerCase();
144 if (keywords && keywords.propertyIsEnumerable(word))
145 return "keyword";
146 if (functions && functions.propertyIsEnumerable(word)) {
147 state.beforeParams = true;
148 return "keyword";
149 }
150 return null;
151 }
152 }
153 function tokenComment(stream, state) {
154 var maybeEnd = false, ch;
155 while (ch = stream.next()) {
156 if (ch == "/" && maybeEnd) {
157 state.tokenize = tokenBase;
158 break;
159 }
160 maybeEnd = (ch == "*");
161 }
162 return "comment";
163 }
164 function tokenUnparsed(stream, state) {
165 var maybeEnd = 0, ch;
166 while (ch = stream.next()) {
167 if (ch == ";" && maybeEnd == 2) {
168 state.tokenize = tokenBase;
169 break;
170 }
171 if (ch == ")")
172 maybeEnd++;
173 else if (ch != " ")
174 maybeEnd = 0;
175 }
176 return "meta";
177 }
178 return {
179 startState: function() {
180 return {
181 tokenize: tokenBase,
182 beforeParams: false,
183 inParams: false
184 };
185 },
186 token: function(stream, state) {
187 if (stream.eatSpace()) return null;
188 return state.tokenize(stream, state);
189 }
190 };
191 });
192
193 });
@@ -1,205 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('mllike', function(_config, parserConfig) {
15 var words = {
16 'let': 'keyword',
17 'rec': 'keyword',
18 'in': 'keyword',
19 'of': 'keyword',
20 'and': 'keyword',
21 'if': 'keyword',
22 'then': 'keyword',
23 'else': 'keyword',
24 'for': 'keyword',
25 'to': 'keyword',
26 'while': 'keyword',
27 'do': 'keyword',
28 'done': 'keyword',
29 'fun': 'keyword',
30 'function': 'keyword',
31 'val': 'keyword',
32 'type': 'keyword',
33 'mutable': 'keyword',
34 'match': 'keyword',
35 'with': 'keyword',
36 'try': 'keyword',
37 'open': 'builtin',
38 'ignore': 'builtin',
39 'begin': 'keyword',
40 'end': 'keyword'
41 };
42
43 var extraWords = parserConfig.extraWords || {};
44 for (var prop in extraWords) {
45 if (extraWords.hasOwnProperty(prop)) {
46 words[prop] = parserConfig.extraWords[prop];
47 }
48 }
49
50 function tokenBase(stream, state) {
51 var ch = stream.next();
52
53 if (ch === '"') {
54 state.tokenize = tokenString;
55 return state.tokenize(stream, state);
56 }
57 if (ch === '(') {
58 if (stream.eat('*')) {
59 state.commentLevel++;
60 state.tokenize = tokenComment;
61 return state.tokenize(stream, state);
62 }
63 }
64 if (ch === '~') {
65 stream.eatWhile(/\w/);
66 return 'variable-2';
67 }
68 if (ch === '`') {
69 stream.eatWhile(/\w/);
70 return 'quote';
71 }
72 if (ch === '/' && parserConfig.slashComments && stream.eat('/')) {
73 stream.skipToEnd();
74 return 'comment';
75 }
76 if (/\d/.test(ch)) {
77 stream.eatWhile(/[\d]/);
78 if (stream.eat('.')) {
79 stream.eatWhile(/[\d]/);
80 }
81 return 'number';
82 }
83 if ( /[+\-*&%=<>!?|]/.test(ch)) {
84 return 'operator';
85 }
86 stream.eatWhile(/\w/);
87 var cur = stream.current();
88 return words[cur] || 'variable';
89 }
90
91 function tokenString(stream, state) {
92 var next, end = false, escaped = false;
93 while ((next = stream.next()) != null) {
94 if (next === '"' && !escaped) {
95 end = true;
96 break;
97 }
98 escaped = !escaped && next === '\\';
99 }
100 if (end && !escaped) {
101 state.tokenize = tokenBase;
102 }
103 return 'string';
104 };
105
106 function tokenComment(stream, state) {
107 var prev, next;
108 while(state.commentLevel > 0 && (next = stream.next()) != null) {
109 if (prev === '(' && next === '*') state.commentLevel++;
110 if (prev === '*' && next === ')') state.commentLevel--;
111 prev = next;
112 }
113 if (state.commentLevel <= 0) {
114 state.tokenize = tokenBase;
115 }
116 return 'comment';
117 }
118
119 return {
120 startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
121 token: function(stream, state) {
122 if (stream.eatSpace()) return null;
123 return state.tokenize(stream, state);
124 },
125
126 blockCommentStart: "(*",
127 blockCommentEnd: "*)",
128 lineComment: parserConfig.slashComments ? "//" : null
129 };
130 });
131
132 CodeMirror.defineMIME('text/x-ocaml', {
133 name: 'mllike',
134 extraWords: {
135 'succ': 'keyword',
136 'trace': 'builtin',
137 'exit': 'builtin',
138 'print_string': 'builtin',
139 'print_endline': 'builtin',
140 'true': 'atom',
141 'false': 'atom',
142 'raise': 'keyword'
143 }
144 });
145
146 CodeMirror.defineMIME('text/x-fsharp', {
147 name: 'mllike',
148 extraWords: {
149 'abstract': 'keyword',
150 'as': 'keyword',
151 'assert': 'keyword',
152 'base': 'keyword',
153 'class': 'keyword',
154 'default': 'keyword',
155 'delegate': 'keyword',
156 'downcast': 'keyword',
157 'downto': 'keyword',
158 'elif': 'keyword',
159 'exception': 'keyword',
160 'extern': 'keyword',
161 'finally': 'keyword',
162 'global': 'keyword',
163 'inherit': 'keyword',
164 'inline': 'keyword',
165 'interface': 'keyword',
166 'internal': 'keyword',
167 'lazy': 'keyword',
168 'let!': 'keyword',
169 'member' : 'keyword',
170 'module': 'keyword',
171 'namespace': 'keyword',
172 'new': 'keyword',
173 'null': 'keyword',
174 'override': 'keyword',
175 'private': 'keyword',
176 'public': 'keyword',
177 'return': 'keyword',
178 'return!': 'keyword',
179 'select': 'keyword',
180 'static': 'keyword',
181 'struct': 'keyword',
182 'upcast': 'keyword',
183 'use': 'keyword',
184 'use!': 'keyword',
185 'val': 'keyword',
186 'when': 'keyword',
187 'yield': 'keyword',
188 'yield!': 'keyword',
189
190 'List': 'builtin',
191 'Seq': 'builtin',
192 'Map': 'builtin',
193 'Set': 'builtin',
194 'int': 'builtin',
195 'string': 'builtin',
196 'raise': 'builtin',
197 'failwith': 'builtin',
198 'not': 'builtin',
199 'true': 'builtin',
200 'false': 'builtin'
201 },
202 slashComments: true
203 });
204
205 });
@@ -1,245 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // Modelica support for CodeMirror, copyright (c) by Lennart Ochel
5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })
14
15 (function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("modelica", function(config, parserConfig) {
19
20 var indentUnit = config.indentUnit;
21 var keywords = parserConfig.keywords || {};
22 var builtin = parserConfig.builtin || {};
23 var atoms = parserConfig.atoms || {};
24
25 var isSingleOperatorChar = /[;=\(:\),{}.*<>+\-\/^\[\]]/;
26 var isDoubleOperatorChar = /(:=|<=|>=|==|<>|\.\+|\.\-|\.\*|\.\/|\.\^)/;
27 var isDigit = /[0-9]/;
28 var isNonDigit = /[_a-zA-Z]/;
29
30 function tokenLineComment(stream, state) {
31 stream.skipToEnd();
32 state.tokenize = null;
33 return "comment";
34 }
35
36 function tokenBlockComment(stream, state) {
37 var maybeEnd = false, ch;
38 while (ch = stream.next()) {
39 if (maybeEnd && ch == "/") {
40 state.tokenize = null;
41 break;
42 }
43 maybeEnd = (ch == "*");
44 }
45 return "comment";
46 }
47
48 function tokenString(stream, state) {
49 var escaped = false, ch;
50 while ((ch = stream.next()) != null) {
51 if (ch == '"' && !escaped) {
52 state.tokenize = null;
53 state.sol = false;
54 break;
55 }
56 escaped = !escaped && ch == "\\";
57 }
58
59 return "string";
60 }
61
62 function tokenIdent(stream, state) {
63 stream.eatWhile(isDigit);
64 while (stream.eat(isDigit) || stream.eat(isNonDigit)) { }
65
66
67 var cur = stream.current();
68
69 if(state.sol && (cur == "package" || cur == "model" || cur == "when" || cur == "connector")) state.level++;
70 else if(state.sol && cur == "end" && state.level > 0) state.level--;
71
72 state.tokenize = null;
73 state.sol = false;
74
75 if (keywords.propertyIsEnumerable(cur)) return "keyword";
76 else if (builtin.propertyIsEnumerable(cur)) return "builtin";
77 else if (atoms.propertyIsEnumerable(cur)) return "atom";
78 else return "variable";
79 }
80
81 function tokenQIdent(stream, state) {
82 while (stream.eat(/[^']/)) { }
83
84 state.tokenize = null;
85 state.sol = false;
86
87 if(stream.eat("'"))
88 return "variable";
89 else
90 return "error";
91 }
92
93 function tokenUnsignedNuber(stream, state) {
94 stream.eatWhile(isDigit);
95 if (stream.eat('.')) {
96 stream.eatWhile(isDigit);
97 }
98 if (stream.eat('e') || stream.eat('E')) {
99 if (!stream.eat('-'))
100 stream.eat('+');
101 stream.eatWhile(isDigit);
102 }
103
104 state.tokenize = null;
105 state.sol = false;
106 return "number";
107 }
108
109 // Interface
110 return {
111 startState: function() {
112 return {
113 tokenize: null,
114 level: 0,
115 sol: true
116 };
117 },
118
119 token: function(stream, state) {
120 if(state.tokenize != null) {
121 return state.tokenize(stream, state);
122 }
123
124 if(stream.sol()) {
125 state.sol = true;
126 }
127
128 // WHITESPACE
129 if(stream.eatSpace()) {
130 state.tokenize = null;
131 return null;
132 }
133
134 var ch = stream.next();
135
136 // LINECOMMENT
137 if(ch == '/' && stream.eat('/')) {
138 state.tokenize = tokenLineComment;
139 }
140 // BLOCKCOMMENT
141 else if(ch == '/' && stream.eat('*')) {
142 state.tokenize = tokenBlockComment;
143 }
144 // TWO SYMBOL TOKENS
145 else if(isDoubleOperatorChar.test(ch+stream.peek())) {
146 stream.next();
147 state.tokenize = null;
148 return "operator";
149 }
150 // SINGLE SYMBOL TOKENS
151 else if(isSingleOperatorChar.test(ch)) {
152 state.tokenize = null;
153 return "operator";
154 }
155 // IDENT
156 else if(isNonDigit.test(ch)) {
157 state.tokenize = tokenIdent;
158 }
159 // Q-IDENT
160 else if(ch == "'" && stream.peek() && stream.peek() != "'") {
161 state.tokenize = tokenQIdent;
162 }
163 // STRING
164 else if(ch == '"') {
165 state.tokenize = tokenString;
166 }
167 // UNSIGNED_NUBER
168 else if(isDigit.test(ch)) {
169 state.tokenize = tokenUnsignedNuber;
170 }
171 // ERROR
172 else {
173 state.tokenize = null;
174 return "error";
175 }
176
177 return state.tokenize(stream, state);
178 },
179
180 indent: function(state, textAfter) {
181 if (state.tokenize != null) return CodeMirror.Pass;
182
183 var level = state.level;
184 if(/(algorithm)/.test(textAfter)) level--;
185 if(/(equation)/.test(textAfter)) level--;
186 if(/(initial algorithm)/.test(textAfter)) level--;
187 if(/(initial equation)/.test(textAfter)) level--;
188 if(/(end)/.test(textAfter)) level--;
189
190 if(level > 0)
191 return indentUnit*level;
192 else
193 return 0;
194 },
195
196 blockCommentStart: "/*",
197 blockCommentEnd: "*/",
198 lineComment: "//"
199 };
200 });
201
202 function words(str) {
203 var obj = {}, words = str.split(" ");
204 for (var i=0; i<words.length; ++i)
205 obj[words[i]] = true;
206 return obj;
207 }
208
209 var modelicaKeywords = "algorithm and annotation assert block break class connect connector constant constrainedby der discrete each else elseif elsewhen encapsulated end enumeration equation expandable extends external false final flow for function if import impure in initial inner input loop model not operator or outer output package parameter partial protected public pure record redeclare replaceable return stream then true type when while within";
210 var modelicaBuiltin = "abs acos actualStream asin atan atan2 cardinality ceil cos cosh delay div edge exp floor getInstanceName homotopy inStream integer log log10 mod pre reinit rem semiLinear sign sin sinh spatialDistribution sqrt tan tanh";
211 var modelicaAtoms = "Real Boolean Integer String";
212
213 function def(mimes, mode) {
214 if (typeof mimes == "string")
215 mimes = [mimes];
216
217 var words = [];
218
219 function add(obj) {
220 if (obj)
221 for (var prop in obj)
222 if (obj.hasOwnProperty(prop))
223 words.push(prop);
224 }
225
226 add(mode.keywords);
227 add(mode.builtin);
228 add(mode.atoms);
229
230 if (words.length) {
231 mode.helperType = mimes[0];
232 CodeMirror.registerHelper("hintWords", mimes[0], words);
233 }
234
235 for (var i=0; i<mimes.length; ++i)
236 CodeMirror.defineMIME(mimes[i], mode);
237 }
238
239 def(["text/x-modelica"], {
240 name: "modelica",
241 keywords: words(modelicaKeywords),
242 builtin: words(modelicaBuiltin),
243 atoms: words(modelicaAtoms)
244 });
245 });
@@ -1,178 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("nginx", function(config) {
15
16 function words(str) {
17 var obj = {}, words = str.split(" ");
18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
19 return obj;
20 }
21
22 var keywords = words(
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"
25 );
26
27 var keywords_block = words(
28 /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
29 );
30
31 var keywords_important = words(
32 /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
33 );
34
35 var indentUnit = config.indentUnit, type;
36 function ret(style, tp) {type = tp; return style;}
37
38 function tokenBase(stream, state) {
39
40
41 stream.eatWhile(/[\w\$_]/);
42
43 var cur = stream.current();
44
45
46 if (keywords.propertyIsEnumerable(cur)) {
47 return "keyword";
48 }
49 else if (keywords_block.propertyIsEnumerable(cur)) {
50 return "variable-2";
51 }
52 else if (keywords_important.propertyIsEnumerable(cur)) {
53 return "string-2";
54 }
55 /**/
56
57 var ch = stream.next();
58 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
59 else if (ch == "/" && stream.eat("*")) {
60 state.tokenize = tokenCComment;
61 return tokenCComment(stream, state);
62 }
63 else if (ch == "<" && stream.eat("!")) {
64 state.tokenize = tokenSGMLComment;
65 return tokenSGMLComment(stream, state);
66 }
67 else if (ch == "=") ret(null, "compare");
68 else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
69 else if (ch == "\"" || ch == "'") {
70 state.tokenize = tokenString(ch);
71 return state.tokenize(stream, state);
72 }
73 else if (ch == "#") {
74 stream.skipToEnd();
75 return ret("comment", "comment");
76 }
77 else if (ch == "!") {
78 stream.match(/^\s*\w*/);
79 return ret("keyword", "important");
80 }
81 else if (/\d/.test(ch)) {
82 stream.eatWhile(/[\w.%]/);
83 return ret("number", "unit");
84 }
85 else if (/[,.+>*\/]/.test(ch)) {
86 return ret(null, "select-op");
87 }
88 else if (/[;{}:\[\]]/.test(ch)) {
89 return ret(null, ch);
90 }
91 else {
92 stream.eatWhile(/[\w\\\-]/);
93 return ret("variable", "variable");
94 }
95 }
96
97 function tokenCComment(stream, state) {
98 var maybeEnd = false, ch;
99 while ((ch = stream.next()) != null) {
100 if (maybeEnd && ch == "/") {
101 state.tokenize = tokenBase;
102 break;
103 }
104 maybeEnd = (ch == "*");
105 }
106 return ret("comment", "comment");
107 }
108
109 function tokenSGMLComment(stream, state) {
110 var dashes = 0, ch;
111 while ((ch = stream.next()) != null) {
112 if (dashes >= 2 && ch == ">") {
113 state.tokenize = tokenBase;
114 break;
115 }
116 dashes = (ch == "-") ? dashes + 1 : 0;
117 }
118 return ret("comment", "comment");
119 }
120
121 function tokenString(quote) {
122 return function(stream, state) {
123 var escaped = false, ch;
124 while ((ch = stream.next()) != null) {
125 if (ch == quote && !escaped)
126 break;
127 escaped = !escaped && ch == "\\";
128 }
129 if (!escaped) state.tokenize = tokenBase;
130 return ret("string", "string");
131 };
132 }
133
134 return {
135 startState: function(base) {
136 return {tokenize: tokenBase,
137 baseIndent: base || 0,
138 stack: []};
139 },
140
141 token: function(stream, state) {
142 if (stream.eatSpace()) return null;
143 type = null;
144 var style = state.tokenize(stream, state);
145
146 var context = state.stack[state.stack.length-1];
147 if (type == "hash" && context == "rule") style = "atom";
148 else if (style == "variable") {
149 if (context == "rule") style = "number";
150 else if (!context || context == "@media{") style = "tag";
151 }
152
153 if (context == "rule" && /^[\{\};]$/.test(type))
154 state.stack.pop();
155 if (type == "{") {
156 if (context == "@media") state.stack[state.stack.length-1] = "@media{";
157 else state.stack.push("{");
158 }
159 else if (type == "}") state.stack.pop();
160 else if (type == "@media") state.stack.push("@media");
161 else if (context == "{" && type != "comment") state.stack.push("rule");
162 return style;
163 },
164
165 indent: function(state, textAfter) {
166 var n = state.stack.length;
167 if (/^\}/.test(textAfter))
168 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
169 return state.baseIndent + n * indentUnit;
170 },
171
172 electricChars: "}"
173 };
174 });
175
176 CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
177
178 });
@@ -1,186 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**********************************************************
5 * This script provides syntax highlighting support for
6 * the Ntriples format.
7 * Ntriples format specification:
8 * http://www.w3.org/TR/rdf-testcases/#ntriples
9 ***********************************************************/
10
11 /*
12 The following expression defines the defined ASF grammar transitions.
13
14 pre_subject ->
15 {
16 ( writing_subject_uri | writing_bnode_uri )
17 -> pre_predicate
18 -> writing_predicate_uri
19 -> pre_object
20 -> writing_object_uri | writing_object_bnode |
21 (
22 writing_object_literal
23 -> writing_literal_lang | writing_literal_type
24 )
25 -> post_object
26 -> BEGIN
27 } otherwise {
28 -> ERROR
29 }
30 */
31
32 (function(mod) {
33 if (typeof exports == "object" && typeof module == "object") // CommonJS
34 mod(require("../../lib/codemirror"));
35 else if (typeof define == "function" && define.amd) // AMD
36 define(["../../lib/codemirror"], mod);
37 else // Plain browser env
38 mod(CodeMirror);
39 })(function(CodeMirror) {
40 "use strict";
41
42 CodeMirror.defineMode("ntriples", function() {
43
44 var Location = {
45 PRE_SUBJECT : 0,
46 WRITING_SUB_URI : 1,
47 WRITING_BNODE_URI : 2,
48 PRE_PRED : 3,
49 WRITING_PRED_URI : 4,
50 PRE_OBJ : 5,
51 WRITING_OBJ_URI : 6,
52 WRITING_OBJ_BNODE : 7,
53 WRITING_OBJ_LITERAL : 8,
54 WRITING_LIT_LANG : 9,
55 WRITING_LIT_TYPE : 10,
56 POST_OBJ : 11,
57 ERROR : 12
58 };
59 function transitState(currState, c) {
60 var currLocation = currState.location;
61 var ret;
62
63 // Opening.
64 if (currLocation == Location.PRE_SUBJECT && c == '<') ret = Location.WRITING_SUB_URI;
65 else if(currLocation == Location.PRE_SUBJECT && c == '_') ret = Location.WRITING_BNODE_URI;
66 else if(currLocation == Location.PRE_PRED && c == '<') ret = Location.WRITING_PRED_URI;
67 else if(currLocation == Location.PRE_OBJ && c == '<') ret = Location.WRITING_OBJ_URI;
68 else if(currLocation == Location.PRE_OBJ && c == '_') ret = Location.WRITING_OBJ_BNODE;
69 else if(currLocation == Location.PRE_OBJ && c == '"') ret = Location.WRITING_OBJ_LITERAL;
70
71 // Closing.
72 else if(currLocation == Location.WRITING_SUB_URI && c == '>') ret = Location.PRE_PRED;
73 else if(currLocation == Location.WRITING_BNODE_URI && c == ' ') ret = Location.PRE_PRED;
74 else if(currLocation == Location.WRITING_PRED_URI && c == '>') ret = Location.PRE_OBJ;
75 else if(currLocation == Location.WRITING_OBJ_URI && c == '>') ret = Location.POST_OBJ;
76 else if(currLocation == Location.WRITING_OBJ_BNODE && c == ' ') ret = Location.POST_OBJ;
77 else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '"') ret = Location.POST_OBJ;
78 else if(currLocation == Location.WRITING_LIT_LANG && c == ' ') ret = Location.POST_OBJ;
79 else if(currLocation == Location.WRITING_LIT_TYPE && c == '>') ret = Location.POST_OBJ;
80
81 // Closing typed and language literal.
82 else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '@') ret = Location.WRITING_LIT_LANG;
83 else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '^') ret = Location.WRITING_LIT_TYPE;
84
85 // Spaces.
86 else if( c == ' ' &&
87 (
88 currLocation == Location.PRE_SUBJECT ||
89 currLocation == Location.PRE_PRED ||
90 currLocation == Location.PRE_OBJ ||
91 currLocation == Location.POST_OBJ
92 )
93 ) ret = currLocation;
94
95 // Reset.
96 else if(currLocation == Location.POST_OBJ && c == '.') ret = Location.PRE_SUBJECT;
97
98 // Error
99 else ret = Location.ERROR;
100
101 currState.location=ret;
102 }
103
104 return {
105 startState: function() {
106 return {
107 location : Location.PRE_SUBJECT,
108 uris : [],
109 anchors : [],
110 bnodes : [],
111 langs : [],
112 types : []
113 };
114 },
115 token: function(stream, state) {
116 var ch = stream.next();
117 if(ch == '<') {
118 transitState(state, ch);
119 var parsedURI = '';
120 stream.eatWhile( function(c) { if( c != '#' && c != '>' ) { parsedURI += c; return true; } return false;} );
121 state.uris.push(parsedURI);
122 if( stream.match('#', false) ) return 'variable';
123 stream.next();
124 transitState(state, '>');
125 return 'variable';
126 }
127 if(ch == '#') {
128 var parsedAnchor = '';
129 stream.eatWhile(function(c) { if(c != '>' && c != ' ') { parsedAnchor+= c; return true; } return false;});
130 state.anchors.push(parsedAnchor);
131 return 'variable-2';
132 }
133 if(ch == '>') {
134 transitState(state, '>');
135 return 'variable';
136 }
137 if(ch == '_') {
138 transitState(state, ch);
139 var parsedBNode = '';
140 stream.eatWhile(function(c) { if( c != ' ' ) { parsedBNode += c; return true; } return false;});
141 state.bnodes.push(parsedBNode);
142 stream.next();
143 transitState(state, ' ');
144 return 'builtin';
145 }
146 if(ch == '"') {
147 transitState(state, ch);
148 stream.eatWhile( function(c) { return c != '"'; } );
149 stream.next();
150 if( stream.peek() != '@' && stream.peek() != '^' ) {
151 transitState(state, '"');
152 }
153 return 'string';
154 }
155 if( ch == '@' ) {
156 transitState(state, '@');
157 var parsedLang = '';
158 stream.eatWhile(function(c) { if( c != ' ' ) { parsedLang += c; return true; } return false;});
159 state.langs.push(parsedLang);
160 stream.next();
161 transitState(state, ' ');
162 return 'string-2';
163 }
164 if( ch == '^' ) {
165 stream.next();
166 transitState(state, '^');
167 var parsedType = '';
168 stream.eatWhile(function(c) { if( c != '>' ) { parsedType += c; return true; } return false;} );
169 state.types.push(parsedType);
170 stream.next();
171 transitState(state, '>');
172 return 'variable';
173 }
174 if( ch == ' ' ) {
175 transitState(state, ch);
176 }
177 if( ch == '.' ) {
178 transitState(state, ch);
179 }
180 }
181 };
182 });
183
184 CodeMirror.defineMIME("text/n-triples", "ntriples");
185
186 });
@@ -1,135 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("octave", function() {
15 function wordRegexp(words) {
16 return new RegExp("^((" + words.join(")|(") + "))\\b");
17 }
18
19 var singleOperators = new RegExp("^[\\+\\-\\*/&|\\^~<>!@'\\\\]");
20 var singleDelimiters = new RegExp('^[\\(\\[\\{\\},:=;]');
21 var doubleOperators = new RegExp("^((==)|(~=)|(<=)|(>=)|(<<)|(>>)|(\\.[\\+\\-\\*/\\^\\\\]))");
22 var doubleDelimiters = new RegExp("^((!=)|(\\+=)|(\\-=)|(\\*=)|(/=)|(&=)|(\\|=)|(\\^=))");
23 var tripleDelimiters = new RegExp("^((>>=)|(<<=))");
24 var expressionEnd = new RegExp("^[\\]\\)]");
25 var identifiers = new RegExp("^[_A-Za-z\xa1-\uffff][_A-Za-z0-9\xa1-\uffff]*");
26
27 var builtins = wordRegexp([
28 'error', 'eval', 'function', 'abs', 'acos', 'atan', 'asin', 'cos',
29 'cosh', 'exp', 'log', 'prod', 'sum', 'log10', 'max', 'min', 'sign', 'sin', 'sinh',
30 'sqrt', 'tan', 'reshape', 'break', 'zeros', 'default', 'margin', 'round', 'ones',
31 'rand', 'syn', 'ceil', 'floor', 'size', 'clear', 'zeros', 'eye', 'mean', 'std', 'cov',
32 'det', 'eig', 'inv', 'norm', 'rank', 'trace', 'expm', 'logm', 'sqrtm', 'linspace', 'plot',
33 'title', 'xlabel', 'ylabel', 'legend', 'text', 'grid', 'meshgrid', 'mesh', 'num2str',
34 'fft', 'ifft', 'arrayfun', 'cellfun', 'input', 'fliplr', 'flipud', 'ismember'
35 ]);
36
37 var keywords = wordRegexp([
38 'return', 'case', 'switch', 'else', 'elseif', 'end', 'endif', 'endfunction',
39 'if', 'otherwise', 'do', 'for', 'while', 'try', 'catch', 'classdef', 'properties', 'events',
40 'methods', 'global', 'persistent', 'endfor', 'endwhile', 'printf', 'sprintf', 'disp', 'until',
41 'continue', 'pkg'
42 ]);
43
44
45 // tokenizers
46 function tokenTranspose(stream, state) {
47 if (!stream.sol() && stream.peek() === '\'') {
48 stream.next();
49 state.tokenize = tokenBase;
50 return 'operator';
51 }
52 state.tokenize = tokenBase;
53 return tokenBase(stream, state);
54 }
55
56
57 function tokenComment(stream, state) {
58 if (stream.match(/^.*%}/)) {
59 state.tokenize = tokenBase;
60 return 'comment';
61 };
62 stream.skipToEnd();
63 return 'comment';
64 }
65
66 function tokenBase(stream, state) {
67 // whitespaces
68 if (stream.eatSpace()) return null;
69
70 // Handle one line Comments
71 if (stream.match('%{')){
72 state.tokenize = tokenComment;
73 stream.skipToEnd();
74 return 'comment';
75 }
76
77 if (stream.match(/^[%#]/)){
78 stream.skipToEnd();
79 return 'comment';
80 }
81
82 // Handle Number Literals
83 if (stream.match(/^[0-9\.+-]/, false)) {
84 if (stream.match(/^[+-]?0x[0-9a-fA-F]+[ij]?/)) {
85 stream.tokenize = tokenBase;
86 return 'number'; };
87 if (stream.match(/^[+-]?\d*\.\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; };
88 if (stream.match(/^[+-]?\d+([EeDd][+-]?\d+)?[ij]?/)) { return 'number'; };
89 }
90 if (stream.match(wordRegexp(['nan','NaN','inf','Inf']))) { return 'number'; };
91
92 // Handle Strings
93 if (stream.match(/^"([^"]|(""))*"/)) { return 'string'; } ;
94 if (stream.match(/^'([^']|(''))*'/)) { return 'string'; } ;
95
96 // Handle words
97 if (stream.match(keywords)) { return 'keyword'; } ;
98 if (stream.match(builtins)) { return 'builtin'; } ;
99 if (stream.match(identifiers)) { return 'variable'; } ;
100
101 if (stream.match(singleOperators) || stream.match(doubleOperators)) { return 'operator'; };
102 if (stream.match(singleDelimiters) || stream.match(doubleDelimiters) || stream.match(tripleDelimiters)) { return null; };
103
104 if (stream.match(expressionEnd)) {
105 state.tokenize = tokenTranspose;
106 return null;
107 };
108
109
110 // Handle non-detected items
111 stream.next();
112 return 'error';
113 };
114
115
116 return {
117 startState: function() {
118 return {
119 tokenize: tokenBase
120 };
121 },
122
123 token: function(stream, state) {
124 var style = state.tokenize(stream, state);
125 if (style === 'number' || style === 'variable'){
126 state.tokenize = tokenTranspose;
127 }
128 return style;
129 }
130 };
131 });
132
133 CodeMirror.defineMIME("text/x-octave", "octave");
134
135 });
@@ -1,109 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("pascal", function() {
15 function words(str) {
16 var obj = {}, words = str.split(" ");
17 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 return obj;
19 }
20 var keywords = words("and array begin case const div do downto else end file for forward integer " +
21 "boolean char function goto if in label mod nil not of or packed procedure " +
22 "program record repeat set string then to type until var while with");
23 var atoms = {"null": true};
24
25 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
26
27 function tokenBase(stream, state) {
28 var ch = stream.next();
29 if (ch == "#" && state.startOfLine) {
30 stream.skipToEnd();
31 return "meta";
32 }
33 if (ch == '"' || ch == "'") {
34 state.tokenize = tokenString(ch);
35 return state.tokenize(stream, state);
36 }
37 if (ch == "(" && stream.eat("*")) {
38 state.tokenize = tokenComment;
39 return tokenComment(stream, state);
40 }
41 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
42 return null;
43 }
44 if (/\d/.test(ch)) {
45 stream.eatWhile(/[\w\.]/);
46 return "number";
47 }
48 if (ch == "/") {
49 if (stream.eat("/")) {
50 stream.skipToEnd();
51 return "comment";
52 }
53 }
54 if (isOperatorChar.test(ch)) {
55 stream.eatWhile(isOperatorChar);
56 return "operator";
57 }
58 stream.eatWhile(/[\w\$_]/);
59 var cur = stream.current();
60 if (keywords.propertyIsEnumerable(cur)) return "keyword";
61 if (atoms.propertyIsEnumerable(cur)) return "atom";
62 return "variable";
63 }
64
65 function tokenString(quote) {
66 return function(stream, state) {
67 var escaped = false, next, end = false;
68 while ((next = stream.next()) != null) {
69 if (next == quote && !escaped) {end = true; break;}
70 escaped = !escaped && next == "\\";
71 }
72 if (end || !escaped) state.tokenize = null;
73 return "string";
74 };
75 }
76
77 function tokenComment(stream, state) {
78 var maybeEnd = false, ch;
79 while (ch = stream.next()) {
80 if (ch == ")" && maybeEnd) {
81 state.tokenize = null;
82 break;
83 }
84 maybeEnd = (ch == "*");
85 }
86 return "comment";
87 }
88
89 // Interface
90
91 return {
92 startState: function() {
93 return {tokenize: null};
94 },
95
96 token: function(stream, state) {
97 if (stream.eatSpace()) return null;
98 var style = (state.tokenize || tokenBase)(stream, state);
99 if (style == "comment" || style == "meta") return style;
100 return style;
101 },
102
103 electricChars: "{}"
104 };
105 });
106
107 CodeMirror.defineMIME("text/x-pascal", "pascal");
108
109 });
@@ -1,114 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../javascript/javascript"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../javascript/javascript"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("pegjs", function (config) {
15 var jsMode = CodeMirror.getMode(config, "javascript");
16
17 function identifier(stream) {
18 return stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
19 }
20
21 return {
22 startState: function () {
23 return {
24 inString: false,
25 stringType: null,
26 inComment: false,
27 inChracterClass: false,
28 braced: 0,
29 lhs: true,
30 localState: null
31 };
32 },
33 token: function (stream, state) {
34 if (stream)
35
36 //check for state changes
37 if (!state.inString && !state.inComment && ((stream.peek() == '"') || (stream.peek() == "'"))) {
38 state.stringType = stream.peek();
39 stream.next(); // Skip quote
40 state.inString = true; // Update state
41 }
42 if (!state.inString && !state.inComment && stream.match(/^\/\*/)) {
43 state.inComment = true;
44 }
45
46 //return state
47 if (state.inString) {
48 while (state.inString && !stream.eol()) {
49 if (stream.peek() === state.stringType) {
50 stream.next(); // Skip quote
51 state.inString = false; // Clear flag
52 } else if (stream.peek() === '\\') {
53 stream.next();
54 stream.next();
55 } else {
56 stream.match(/^.[^\\\"\']*/);
57 }
58 }
59 return state.lhs ? "property string" : "string"; // Token style
60 } else if (state.inComment) {
61 while (state.inComment && !stream.eol()) {
62 if (stream.match(/\*\//)) {
63 state.inComment = false; // Clear flag
64 } else {
65 stream.match(/^.[^\*]*/);
66 }
67 }
68 return "comment";
69 } else if (state.inChracterClass) {
70 while (state.inChracterClass && !stream.eol()) {
71 if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
72 state.inChracterClass = false;
73 }
74 }
75 } else if (stream.peek() === '[') {
76 stream.next();
77 state.inChracterClass = true;
78 return 'bracket';
79 } else if (stream.match(/^\/\//)) {
80 stream.skipToEnd();
81 return "comment";
82 } else if (state.braced || stream.peek() === '{') {
83 if (state.localState === null) {
84 state.localState = jsMode.startState();
85 }
86 var token = jsMode.token(stream, state.localState);
87 var text = stream.current();
88 if (!token) {
89 for (var i = 0; i < text.length; i++) {
90 if (text[i] === '{') {
91 state.braced++;
92 } else if (text[i] === '}') {
93 state.braced--;
94 }
95 };
96 }
97 return token;
98 } else if (identifier(stream)) {
99 if (stream.peek() === ':') {
100 return 'variable';
101 }
102 return 'variable-2';
103 } else if (['[', ']', '(', ')'].indexOf(stream.peek()) != -1) {
104 stream.next();
105 return 'bracket';
106 } else if (!stream.eatSpace()) {
107 stream.next();
108 }
109 return null;
110 }
111 };
112 }, "javascript");
113
114 });
This diff has been collapsed as it changes many lines, (832 lines changed) Show them Hide them
@@ -1,832 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
5 // This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)
6
7 (function(mod) {
8 if (typeof exports == "object" && typeof module == "object") // CommonJS
9 mod(require("../../lib/codemirror"));
10 else if (typeof define == "function" && define.amd) // AMD
11 define(["../../lib/codemirror"], mod);
12 else // Plain browser env
13 mod(CodeMirror);
14 })(function(CodeMirror) {
15 "use strict";
16
17 CodeMirror.defineMode("perl",function(){
18 // http://perldoc.perl.org
19 var PERL={ // null - magic touch
20 // 1 - keyword
21 // 2 - def
22 // 3 - atom
23 // 4 - operator
24 // 5 - variable-2 (predefined)
25 // [x,y] - x=1,2,3; y=must be defined if x{...}
26 // PERL operators
27 '->' : 4,
28 '++' : 4,
29 '--' : 4,
30 '**' : 4,
31 // ! ~ \ and unary + and -
32 '=~' : 4,
33 '!~' : 4,
34 '*' : 4,
35 '/' : 4,
36 '%' : 4,
37 'x' : 4,
38 '+' : 4,
39 '-' : 4,
40 '.' : 4,
41 '<<' : 4,
42 '>>' : 4,
43 // named unary operators
44 '<' : 4,
45 '>' : 4,
46 '<=' : 4,
47 '>=' : 4,
48 'lt' : 4,
49 'gt' : 4,
50 'le' : 4,
51 'ge' : 4,
52 '==' : 4,
53 '!=' : 4,
54 '<=>' : 4,
55 'eq' : 4,
56 'ne' : 4,
57 'cmp' : 4,
58 '~~' : 4,
59 '&' : 4,
60 '|' : 4,
61 '^' : 4,
62 '&&' : 4,
63 '||' : 4,
64 '//' : 4,
65 '..' : 4,
66 '...' : 4,
67 '?' : 4,
68 ':' : 4,
69 '=' : 4,
70 '+=' : 4,
71 '-=' : 4,
72 '*=' : 4, // etc. ???
73 ',' : 4,
74 '=>' : 4,
75 '::' : 4,
76 // list operators (rightward)
77 'not' : 4,
78 'and' : 4,
79 'or' : 4,
80 'xor' : 4,
81 // PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;)
82 'BEGIN' : [5,1],
83 'END' : [5,1],
84 'PRINT' : [5,1],
85 'PRINTF' : [5,1],
86 'GETC' : [5,1],
87 'READ' : [5,1],
88 'READLINE' : [5,1],
89 'DESTROY' : [5,1],
90 'TIE' : [5,1],
91 'TIEHANDLE' : [5,1],
92 'UNTIE' : [5,1],
93 'STDIN' : 5,
94 'STDIN_TOP' : 5,
95 'STDOUT' : 5,
96 'STDOUT_TOP' : 5,
97 'STDERR' : 5,
98 'STDERR_TOP' : 5,
99 '$ARG' : 5,
100 '$_' : 5,
101 '@ARG' : 5,
102 '@_' : 5,
103 '$LIST_SEPARATOR' : 5,
104 '$"' : 5,
105 '$PROCESS_ID' : 5,
106 '$PID' : 5,
107 '$$' : 5,
108 '$REAL_GROUP_ID' : 5,
109 '$GID' : 5,
110 '$(' : 5,
111 '$EFFECTIVE_GROUP_ID' : 5,
112 '$EGID' : 5,
113 '$)' : 5,
114 '$PROGRAM_NAME' : 5,
115 '$0' : 5,
116 '$SUBSCRIPT_SEPARATOR' : 5,
117 '$SUBSEP' : 5,
118 '$;' : 5,
119 '$REAL_USER_ID' : 5,
120 '$UID' : 5,
121 '$<' : 5,
122 '$EFFECTIVE_USER_ID' : 5,
123 '$EUID' : 5,
124 '$>' : 5,
125 '$a' : 5,
126 '$b' : 5,
127 '$COMPILING' : 5,
128 '$^C' : 5,
129 '$DEBUGGING' : 5,
130 '$^D' : 5,
131 '${^ENCODING}' : 5,
132 '$ENV' : 5,
133 '%ENV' : 5,
134 '$SYSTEM_FD_MAX' : 5,
135 '$^F' : 5,
136 '@F' : 5,
137 '${^GLOBAL_PHASE}' : 5,
138 '$^H' : 5,
139 '%^H' : 5,
140 '@INC' : 5,
141 '%INC' : 5,
142 '$INPLACE_EDIT' : 5,
143 '$^I' : 5,
144 '$^M' : 5,
145 '$OSNAME' : 5,
146 '$^O' : 5,
147 '${^OPEN}' : 5,
148 '$PERLDB' : 5,
149 '$^P' : 5,
150 '$SIG' : 5,
151 '%SIG' : 5,
152 '$BASETIME' : 5,
153 '$^T' : 5,
154 '${^TAINT}' : 5,
155 '${^UNICODE}' : 5,
156 '${^UTF8CACHE}' : 5,
157 '${^UTF8LOCALE}' : 5,
158 '$PERL_VERSION' : 5,
159 '$^V' : 5,
160 '${^WIN32_SLOPPY_STAT}' : 5,
161 '$EXECUTABLE_NAME' : 5,
162 '$^X' : 5,
163 '$1' : 5, // - regexp $1, $2...
164 '$MATCH' : 5,
165 '$&' : 5,
166 '${^MATCH}' : 5,
167 '$PREMATCH' : 5,
168 '$`' : 5,
169 '${^PREMATCH}' : 5,
170 '$POSTMATCH' : 5,
171 "$'" : 5,
172 '${^POSTMATCH}' : 5,
173 '$LAST_PAREN_MATCH' : 5,
174 '$+' : 5,
175 '$LAST_SUBMATCH_RESULT' : 5,
176 '$^N' : 5,
177 '@LAST_MATCH_END' : 5,
178 '@+' : 5,
179 '%LAST_PAREN_MATCH' : 5,
180 '%+' : 5,
181 '@LAST_MATCH_START' : 5,
182 '@-' : 5,
183 '%LAST_MATCH_START' : 5,
184 '%-' : 5,
185 '$LAST_REGEXP_CODE_RESULT' : 5,
186 '$^R' : 5,
187 '${^RE_DEBUG_FLAGS}' : 5,
188 '${^RE_TRIE_MAXBUF}' : 5,
189 '$ARGV' : 5,
190 '@ARGV' : 5,
191 'ARGV' : 5,
192 'ARGVOUT' : 5,
193 '$OUTPUT_FIELD_SEPARATOR' : 5,
194 '$OFS' : 5,
195 '$,' : 5,
196 '$INPUT_LINE_NUMBER' : 5,
197 '$NR' : 5,
198 '$.' : 5,
199 '$INPUT_RECORD_SEPARATOR' : 5,
200 '$RS' : 5,
201 '$/' : 5,
202 '$OUTPUT_RECORD_SEPARATOR' : 5,
203 '$ORS' : 5,
204 '$\\' : 5,
205 '$OUTPUT_AUTOFLUSH' : 5,
206 '$|' : 5,
207 '$ACCUMULATOR' : 5,
208 '$^A' : 5,
209 '$FORMAT_FORMFEED' : 5,
210 '$^L' : 5,
211 '$FORMAT_PAGE_NUMBER' : 5,
212 '$%' : 5,
213 '$FORMAT_LINES_LEFT' : 5,
214 '$-' : 5,
215 '$FORMAT_LINE_BREAK_CHARACTERS' : 5,
216 '$:' : 5,
217 '$FORMAT_LINES_PER_PAGE' : 5,
218 '$=' : 5,
219 '$FORMAT_TOP_NAME' : 5,
220 '$^' : 5,
221 '$FORMAT_NAME' : 5,
222 '$~' : 5,
223 '${^CHILD_ERROR_NATIVE}' : 5,
224 '$EXTENDED_OS_ERROR' : 5,
225 '$^E' : 5,
226 '$EXCEPTIONS_BEING_CAUGHT' : 5,
227 '$^S' : 5,
228 '$WARNING' : 5,
229 '$^W' : 5,
230 '${^WARNING_BITS}' : 5,
231 '$OS_ERROR' : 5,
232 '$ERRNO' : 5,
233 '$!' : 5,
234 '%OS_ERROR' : 5,
235 '%ERRNO' : 5,
236 '%!' : 5,
237 '$CHILD_ERROR' : 5,
238 '$?' : 5,
239 '$EVAL_ERROR' : 5,
240 '$@' : 5,
241 '$OFMT' : 5,
242 '$#' : 5,
243 '$*' : 5,
244 '$ARRAY_BASE' : 5,
245 '$[' : 5,
246 '$OLD_PERL_VERSION' : 5,
247 '$]' : 5,
248 // PERL blocks
249 'if' :[1,1],
250 elsif :[1,1],
251 'else' :[1,1],
252 'while' :[1,1],
253 unless :[1,1],
254 'for' :[1,1],
255 foreach :[1,1],
256 // PERL functions
257 'abs' :1, // - absolute value function
258 accept :1, // - accept an incoming socket connect
259 alarm :1, // - schedule a SIGALRM
260 'atan2' :1, // - arctangent of Y/X in the range -PI to PI
261 bind :1, // - binds an address to a socket
262 binmode :1, // - prepare binary files for I/O
263 bless :1, // - create an object
264 bootstrap :1, //
265 'break' :1, // - break out of a "given" block
266 caller :1, // - get context of the current subroutine call
267 chdir :1, // - change your current working directory
268 chmod :1, // - changes the permissions on a list of files
269 chomp :1, // - remove a trailing record separator from a string
270 chop :1, // - remove the last character from a string
271 chown :1, // - change the owership on a list of files
272 chr :1, // - get character this number represents
273 chroot :1, // - make directory new root for path lookups
274 close :1, // - close file (or pipe or socket) handle
275 closedir :1, // - close directory handle
276 connect :1, // - connect to a remote socket
277 'continue' :[1,1], // - optional trailing block in a while or foreach
278 'cos' :1, // - cosine function
279 crypt :1, // - one-way passwd-style encryption
280 dbmclose :1, // - breaks binding on a tied dbm file
281 dbmopen :1, // - create binding on a tied dbm file
282 'default' :1, //
283 defined :1, // - test whether a value, variable, or function is defined
284 'delete' :1, // - deletes a value from a hash
285 die :1, // - raise an exception or bail out
286 'do' :1, // - turn a BLOCK into a TERM
287 dump :1, // - create an immediate core dump
288 each :1, // - retrieve the next key/value pair from a hash
289 endgrent :1, // - be done using group file
290 endhostent :1, // - be done using hosts file
291 endnetent :1, // - be done using networks file
292 endprotoent :1, // - be done using protocols file
293 endpwent :1, // - be done using passwd file
294 endservent :1, // - be done using services file
295 eof :1, // - test a filehandle for its end
296 'eval' :1, // - catch exceptions or compile and run code
297 'exec' :1, // - abandon this program to run another
298 exists :1, // - test whether a hash key is present
299 exit :1, // - terminate this program
300 'exp' :1, // - raise I to a power
301 fcntl :1, // - file control system call
302 fileno :1, // - return file descriptor from filehandle
303 flock :1, // - lock an entire file with an advisory lock
304 fork :1, // - create a new process just like this one
305 format :1, // - declare a picture format with use by the write() function
306 formline :1, // - internal function used for formats
307 getc :1, // - get the next character from the filehandle
308 getgrent :1, // - get next group record
309 getgrgid :1, // - get group record given group user ID
310 getgrnam :1, // - get group record given group name
311 gethostbyaddr :1, // - get host record given its address
312 gethostbyname :1, // - get host record given name
313 gethostent :1, // - get next hosts record
314 getlogin :1, // - return who logged in at this tty
315 getnetbyaddr :1, // - get network record given its address
316 getnetbyname :1, // - get networks record given name
317 getnetent :1, // - get next networks record
318 getpeername :1, // - find the other end of a socket connection
319 getpgrp :1, // - get process group
320 getppid :1, // - get parent process ID
321 getpriority :1, // - get current nice value
322 getprotobyname :1, // - get protocol record given name
323 getprotobynumber :1, // - get protocol record numeric protocol
324 getprotoent :1, // - get next protocols record
325 getpwent :1, // - get next passwd record
326 getpwnam :1, // - get passwd record given user login name
327 getpwuid :1, // - get passwd record given user ID
328 getservbyname :1, // - get services record given its name
329 getservbyport :1, // - get services record given numeric port
330 getservent :1, // - get next services record
331 getsockname :1, // - retrieve the sockaddr for a given socket
332 getsockopt :1, // - get socket options on a given socket
333 given :1, //
334 glob :1, // - expand filenames using wildcards
335 gmtime :1, // - convert UNIX time into record or string using Greenwich time
336 'goto' :1, // - create spaghetti code
337 grep :1, // - locate elements in a list test true against a given criterion
338 hex :1, // - convert a string to a hexadecimal number
339 'import' :1, // - patch a module's namespace into your own
340 index :1, // - find a substring within a string
341 'int' :1, // - get the integer portion of a number
342 ioctl :1, // - system-dependent device control system call
343 'join' :1, // - join a list into a string using a separator
344 keys :1, // - retrieve list of indices from a hash
345 kill :1, // - send a signal to a process or process group
346 last :1, // - exit a block prematurely
347 lc :1, // - return lower-case version of a string
348 lcfirst :1, // - return a string with just the next letter in lower case
349 length :1, // - return the number of bytes in a string
350 'link' :1, // - create a hard link in the filesytem
351 listen :1, // - register your socket as a server
352 local : 2, // - create a temporary value for a global variable (dynamic scoping)
353 localtime :1, // - convert UNIX time into record or string using local time
354 lock :1, // - get a thread lock on a variable, subroutine, or method
355 'log' :1, // - retrieve the natural logarithm for a number
356 lstat :1, // - stat a symbolic link
357 m :null, // - match a string with a regular expression pattern
358 map :1, // - apply a change to a list to get back a new list with the changes
359 mkdir :1, // - create a directory
360 msgctl :1, // - SysV IPC message control operations
361 msgget :1, // - get SysV IPC message queue
362 msgrcv :1, // - receive a SysV IPC message from a message queue
363 msgsnd :1, // - send a SysV IPC message to a message queue
364 my : 2, // - declare and assign a local variable (lexical scoping)
365 'new' :1, //
366 next :1, // - iterate a block prematurely
367 no :1, // - unimport some module symbols or semantics at compile time
368 oct :1, // - convert a string to an octal number
369 open :1, // - open a file, pipe, or descriptor
370 opendir :1, // - open a directory
371 ord :1, // - find a character's numeric representation
372 our : 2, // - declare and assign a package variable (lexical scoping)
373 pack :1, // - convert a list into a binary representation
374 'package' :1, // - declare a separate global namespace
375 pipe :1, // - open a pair of connected filehandles
376 pop :1, // - remove the last element from an array and return it
377 pos :1, // - find or set the offset for the last/next m//g search
378 print :1, // - output a list to a filehandle
379 printf :1, // - output a formatted list to a filehandle
380 prototype :1, // - get the prototype (if any) of a subroutine
381 push :1, // - append one or more elements to an array
382 q :null, // - singly quote a string
383 qq :null, // - doubly quote a string
384 qr :null, // - Compile pattern
385 quotemeta :null, // - quote regular expression magic characters
386 qw :null, // - quote a list of words
387 qx :null, // - backquote quote a string
388 rand :1, // - retrieve the next pseudorandom number
389 read :1, // - fixed-length buffered input from a filehandle
390 readdir :1, // - get a directory from a directory handle
391 readline :1, // - fetch a record from a file
392 readlink :1, // - determine where a symbolic link is pointing
393 readpipe :1, // - execute a system command and collect standard output
394 recv :1, // - receive a message over a Socket
395 redo :1, // - start this loop iteration over again
396 ref :1, // - find out the type of thing being referenced
397 rename :1, // - change a filename
398 require :1, // - load in external functions from a library at runtime
399 reset :1, // - clear all variables of a given name
400 'return' :1, // - get out of a function early
401 reverse :1, // - flip a string or a list
402 rewinddir :1, // - reset directory handle
403 rindex :1, // - right-to-left substring search
404 rmdir :1, // - remove a directory
405 s :null, // - replace a pattern with a string
406 say :1, // - print with newline
407 scalar :1, // - force a scalar context
408 seek :1, // - reposition file pointer for random-access I/O
409 seekdir :1, // - reposition directory pointer
410 select :1, // - reset default output or do I/O multiplexing
411 semctl :1, // - SysV semaphore control operations
412 semget :1, // - get set of SysV semaphores
413 semop :1, // - SysV semaphore operations
414 send :1, // - send a message over a socket
415 setgrent :1, // - prepare group file for use
416 sethostent :1, // - prepare hosts file for use
417 setnetent :1, // - prepare networks file for use
418 setpgrp :1, // - set the process group of a process
419 setpriority :1, // - set a process's nice value
420 setprotoent :1, // - prepare protocols file for use
421 setpwent :1, // - prepare passwd file for use
422 setservent :1, // - prepare services file for use
423 setsockopt :1, // - set some socket options
424 shift :1, // - remove the first element of an array, and return it
425 shmctl :1, // - SysV shared memory operations
426 shmget :1, // - get SysV shared memory segment identifier
427 shmread :1, // - read SysV shared memory
428 shmwrite :1, // - write SysV shared memory
429 shutdown :1, // - close down just half of a socket connection
430 'sin' :1, // - return the sine of a number
431 sleep :1, // - block for some number of seconds
432 socket :1, // - create a socket
433 socketpair :1, // - create a pair of sockets
434 'sort' :1, // - sort a list of values
435 splice :1, // - add or remove elements anywhere in an array
436 'split' :1, // - split up a string using a regexp delimiter
437 sprintf :1, // - formatted print into a string
438 'sqrt' :1, // - square root function
439 srand :1, // - seed the random number generator
440 stat :1, // - get a file's status information
441 state :1, // - declare and assign a state variable (persistent lexical scoping)
442 study :1, // - optimize input data for repeated searches
443 'sub' :1, // - declare a subroutine, possibly anonymously
444 'substr' :1, // - get or alter a portion of a stirng
445 symlink :1, // - create a symbolic link to a file
446 syscall :1, // - execute an arbitrary system call
447 sysopen :1, // - open a file, pipe, or descriptor
448 sysread :1, // - fixed-length unbuffered input from a filehandle
449 sysseek :1, // - position I/O pointer on handle used with sysread and syswrite
450 system :1, // - run a separate program
451 syswrite :1, // - fixed-length unbuffered output to a filehandle
452 tell :1, // - get current seekpointer on a filehandle
453 telldir :1, // - get current seekpointer on a directory handle
454 tie :1, // - bind a variable to an object class
455 tied :1, // - get a reference to the object underlying a tied variable
456 time :1, // - return number of seconds since 1970
457 times :1, // - return elapsed time for self and child processes
458 tr :null, // - transliterate a string
459 truncate :1, // - shorten a file
460 uc :1, // - return upper-case version of a string
461 ucfirst :1, // - return a string with just the next letter in upper case
462 umask :1, // - set file creation mode mask
463 undef :1, // - remove a variable or function definition
464 unlink :1, // - remove one link to a file
465 unpack :1, // - convert binary structure into normal perl variables
466 unshift :1, // - prepend more elements to the beginning of a list
467 untie :1, // - break a tie binding to a variable
468 use :1, // - load in a module at compile time
469 utime :1, // - set a file's last access and modify times
470 values :1, // - return a list of the values in a hash
471 vec :1, // - test or set particular bits in a string
472 wait :1, // - wait for any child process to die
473 waitpid :1, // - wait for a particular child process to die
474 wantarray :1, // - get void vs scalar vs list context of current subroutine call
475 warn :1, // - print debugging info
476 when :1, //
477 write :1, // - print a picture record
478 y :null}; // - transliterate a string
479
480 var RXstyle="string-2";
481 var RXmodifiers=/[goseximacplud]/; // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type
482
483 function tokenChain(stream,state,chain,style,tail){ // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)
484 state.chain=null; // 12 3tail
485 state.style=null;
486 state.tail=null;
487 state.tokenize=function(stream,state){
488 var e=false,c,i=0;
489 while(c=stream.next()){
490 if(c===chain[i]&&!e){
491 if(chain[++i]!==undefined){
492 state.chain=chain[i];
493 state.style=style;
494 state.tail=tail;}
495 else if(tail)
496 stream.eatWhile(tail);
497 state.tokenize=tokenPerl;
498 return style;}
499 e=!e&&c=="\\";}
500 return style;};
501 return state.tokenize(stream,state);}
502
503 function tokenSOMETHING(stream,state,string){
504 state.tokenize=function(stream,state){
505 if(stream.string==string)
506 state.tokenize=tokenPerl;
507 stream.skipToEnd();
508 return "string";};
509 return state.tokenize(stream,state);}
510
511 function tokenPerl(stream,state){
512 if(stream.eatSpace())
513 return null;
514 if(state.chain)
515 return tokenChain(stream,state,state.chain,state.style,state.tail);
516 if(stream.match(/^\-?[\d\.]/,false))
517 if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
518 return 'number';
519 if(stream.match(/^<<(?=\w)/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
520 stream.eatWhile(/\w/);
521 return tokenSOMETHING(stream,state,stream.current().substr(2));}
522 if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
523 return tokenSOMETHING(stream,state,'=cut');}
524 var ch=stream.next();
525 if(ch=='"'||ch=="'"){ // NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\n
526 if(prefix(stream, 3)=="<<"+ch){
527 var p=stream.pos;
528 stream.eatWhile(/\w/);
529 var n=stream.current().substr(1);
530 if(n&&stream.eat(ch))
531 return tokenSOMETHING(stream,state,n);
532 stream.pos=p;}
533 return tokenChain(stream,state,[ch],"string");}
534 if(ch=="q"){
535 var c=look(stream, -2);
536 if(!(c&&/\w/.test(c))){
537 c=look(stream, 0);
538 if(c=="x"){
539 c=look(stream, 1);
540 if(c=="("){
541 eatSuffix(stream, 2);
542 return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
543 if(c=="["){
544 eatSuffix(stream, 2);
545 return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
546 if(c=="{"){
547 eatSuffix(stream, 2);
548 return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
549 if(c=="<"){
550 eatSuffix(stream, 2);
551 return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
552 if(/[\^'"!~\/]/.test(c)){
553 eatSuffix(stream, 1);
554 return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
555 else if(c=="q"){
556 c=look(stream, 1);
557 if(c=="("){
558 eatSuffix(stream, 2);
559 return tokenChain(stream,state,[")"],"string");}
560 if(c=="["){
561 eatSuffix(stream, 2);
562 return tokenChain(stream,state,["]"],"string");}
563 if(c=="{"){
564 eatSuffix(stream, 2);
565 return tokenChain(stream,state,["}"],"string");}
566 if(c=="<"){
567 eatSuffix(stream, 2);
568 return tokenChain(stream,state,[">"],"string");}
569 if(/[\^'"!~\/]/.test(c)){
570 eatSuffix(stream, 1);
571 return tokenChain(stream,state,[stream.eat(c)],"string");}}
572 else if(c=="w"){
573 c=look(stream, 1);
574 if(c=="("){
575 eatSuffix(stream, 2);
576 return tokenChain(stream,state,[")"],"bracket");}
577 if(c=="["){
578 eatSuffix(stream, 2);
579 return tokenChain(stream,state,["]"],"bracket");}
580 if(c=="{"){
581 eatSuffix(stream, 2);
582 return tokenChain(stream,state,["}"],"bracket");}
583 if(c=="<"){
584 eatSuffix(stream, 2);
585 return tokenChain(stream,state,[">"],"bracket");}
586 if(/[\^'"!~\/]/.test(c)){
587 eatSuffix(stream, 1);
588 return tokenChain(stream,state,[stream.eat(c)],"bracket");}}
589 else if(c=="r"){
590 c=look(stream, 1);
591 if(c=="("){
592 eatSuffix(stream, 2);
593 return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
594 if(c=="["){
595 eatSuffix(stream, 2);
596 return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
597 if(c=="{"){
598 eatSuffix(stream, 2);
599 return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
600 if(c=="<"){
601 eatSuffix(stream, 2);
602 return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
603 if(/[\^'"!~\/]/.test(c)){
604 eatSuffix(stream, 1);
605 return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
606 else if(/[\^'"!~\/(\[{<]/.test(c)){
607 if(c=="("){
608 eatSuffix(stream, 1);
609 return tokenChain(stream,state,[")"],"string");}
610 if(c=="["){
611 eatSuffix(stream, 1);
612 return tokenChain(stream,state,["]"],"string");}
613 if(c=="{"){
614 eatSuffix(stream, 1);
615 return tokenChain(stream,state,["}"],"string");}
616 if(c=="<"){
617 eatSuffix(stream, 1);
618 return tokenChain(stream,state,[">"],"string");}
619 if(/[\^'"!~\/]/.test(c)){
620 return tokenChain(stream,state,[stream.eat(c)],"string");}}}}
621 if(ch=="m"){
622 var c=look(stream, -2);
623 if(!(c&&/\w/.test(c))){
624 c=stream.eat(/[(\[{<\^'"!~\/]/);
625 if(c){
626 if(/[\^'"!~\/]/.test(c)){
627 return tokenChain(stream,state,[c],RXstyle,RXmodifiers);}
628 if(c=="("){
629 return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
630 if(c=="["){
631 return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
632 if(c=="{"){
633 return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
634 if(c=="<"){
635 return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}}
636 if(ch=="s"){
637 var c=/[\/>\]})\w]/.test(look(stream, -2));
638 if(!c){
639 c=stream.eat(/[(\[{<\^'"!~\/]/);
640 if(c){
641 if(c=="[")
642 return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
643 if(c=="{")
644 return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
645 if(c=="<")
646 return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
647 if(c=="(")
648 return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
649 return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
650 if(ch=="y"){
651 var c=/[\/>\]})\w]/.test(look(stream, -2));
652 if(!c){
653 c=stream.eat(/[(\[{<\^'"!~\/]/);
654 if(c){
655 if(c=="[")
656 return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
657 if(c=="{")
658 return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
659 if(c=="<")
660 return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
661 if(c=="(")
662 return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
663 return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
664 if(ch=="t"){
665 var c=/[\/>\]})\w]/.test(look(stream, -2));
666 if(!c){
667 c=stream.eat("r");if(c){
668 c=stream.eat(/[(\[{<\^'"!~\/]/);
669 if(c){
670 if(c=="[")
671 return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
672 if(c=="{")
673 return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
674 if(c=="<")
675 return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
676 if(c=="(")
677 return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
678 return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}}
679 if(ch=="`"){
680 return tokenChain(stream,state,[ch],"variable-2");}
681 if(ch=="/"){
682 if(!/~\s*$/.test(prefix(stream)))
683 return "operator";
684 else
685 return tokenChain(stream,state,[ch],RXstyle,RXmodifiers);}
686 if(ch=="$"){
687 var p=stream.pos;
688 if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))
689 return "variable-2";
690 else
691 stream.pos=p;}
692 if(/[$@%]/.test(ch)){
693 var p=stream.pos;
694 if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(look(stream, -2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){
695 var c=stream.current();
696 if(PERL[c])
697 return "variable-2";}
698 stream.pos=p;}
699 if(/[$@%&]/.test(ch)){
700 if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
701 var c=stream.current();
702 if(PERL[c])
703 return "variable-2";
704 else
705 return "variable";}}
706 if(ch=="#"){
707 if(look(stream, -2)!="$"){
708 stream.skipToEnd();
709 return "comment";}}
710 if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){
711 var p=stream.pos;
712 stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);
713 if(PERL[stream.current()])
714 return "operator";
715 else
716 stream.pos=p;}
717 if(ch=="_"){
718 if(stream.pos==1){
719 if(suffix(stream, 6)=="_END__"){
720 return tokenChain(stream,state,['\0'],"comment");}
721 else if(suffix(stream, 7)=="_DATA__"){
722 return tokenChain(stream,state,['\0'],"variable-2");}
723 else if(suffix(stream, 7)=="_C__"){
724 return tokenChain(stream,state,['\0'],"string");}}}
725 if(/\w/.test(ch)){
726 var p=stream.pos;
727 if(look(stream, -2)=="{"&&(look(stream, 0)=="}"||stream.eatWhile(/\w/)&&look(stream, 0)=="}"))
728 return "string";
729 else
730 stream.pos=p;}
731 if(/[A-Z]/.test(ch)){
732 var l=look(stream, -2);
733 var p=stream.pos;
734 stream.eatWhile(/[A-Z_]/);
735 if(/[\da-z]/.test(look(stream, 0))){
736 stream.pos=p;}
737 else{
738 var c=PERL[stream.current()];
739 if(!c)
740 return "meta";
741 if(c[1])
742 c=c[0];
743 if(l!=":"){
744 if(c==1)
745 return "keyword";
746 else if(c==2)
747 return "def";
748 else if(c==3)
749 return "atom";
750 else if(c==4)
751 return "operator";
752 else if(c==5)
753 return "variable-2";
754 else
755 return "meta";}
756 else
757 return "meta";}}
758 if(/[a-zA-Z_]/.test(ch)){
759 var l=look(stream, -2);
760 stream.eatWhile(/\w/);
761 var c=PERL[stream.current()];
762 if(!c)
763 return "meta";
764 if(c[1])
765 c=c[0];
766 if(l!=":"){
767 if(c==1)
768 return "keyword";
769 else if(c==2)
770 return "def";
771 else if(c==3)
772 return "atom";
773 else if(c==4)
774 return "operator";
775 else if(c==5)
776 return "variable-2";
777 else
778 return "meta";}
779 else
780 return "meta";}
781 return null;}
782
783 return{
784 startState:function(){
785 return{
786 tokenize:tokenPerl,
787 chain:null,
788 style:null,
789 tail:null};},
790 token:function(stream,state){
791 return (state.tokenize||tokenPerl)(stream,state);}
792 };});
793
794 CodeMirror.registerHelper("wordChars", "perl", /[\w$]/);
795
796 CodeMirror.defineMIME("text/x-perl", "perl");
797
798 // it's like "peek", but need for look-ahead or look-behind if index < 0
799 function look(stream, c){
800 return stream.string.charAt(stream.pos+(c||0));
801 }
802
803 // return a part of prefix of current stream from current position
804 function prefix(stream, c){
805 if(c){
806 var x=stream.pos-c;
807 return stream.string.substr((x>=0?x:0),c);}
808 else{
809 return stream.string.substr(0,stream.pos-1);
810 }
811 }
812
813 // return a part of suffix of current stream from current position
814 function suffix(stream, c){
815 var y=stream.string.length;
816 var x=y-stream.pos+1;
817 return stream.string.substr(stream.pos,(c&&c<y?c:x));
818 }
819
820 // eating and vomiting a part of stream from current position
821 function eatSuffix(stream, c){
822 var x=stream.pos+c;
823 var y;
824 if(x<=0)
825 stream.pos=0;
826 else if(x>=(y=stream.string.length-1))
827 stream.pos=y;
828 else
829 stream.pos=x;
830 }
831
832 });
@@ -1,226 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 function keywords(str) {
15 var obj = {}, words = str.split(" ");
16 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
17 return obj;
18 }
19
20 // Helper for stringWithEscapes
21 function matchSequence(list, end) {
22 if (list.length == 0) return stringWithEscapes(end);
23 return function (stream, state) {
24 var patterns = list[0];
25 for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
26 state.tokenize = matchSequence(list.slice(1), end);
27 return patterns[i][1];
28 }
29 state.tokenize = stringWithEscapes(end);
30 return "string";
31 };
32 }
33 function stringWithEscapes(closing) {
34 return function(stream, state) { return stringWithEscapes_(stream, state, closing); };
35 }
36 function stringWithEscapes_(stream, state, closing) {
37 // "Complex" syntax
38 if (stream.match("${", false) || stream.match("{$", false)) {
39 state.tokenize = null;
40 return "string";
41 }
42
43 // Simple syntax
44 if (stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
45 // After the variable name there may appear array or object operator.
46 if (stream.match("[", false)) {
47 // Match array operator
48 state.tokenize = matchSequence([
49 [["[", null]],
50 [[/\d[\w\.]*/, "number"],
51 [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
52 [/[\w\$]+/, "variable"]],
53 [["]", null]]
54 ], closing);
55 }
56 if (stream.match(/\-\>\w/, false)) {
57 // Match object operator
58 state.tokenize = matchSequence([
59 [["->", null]],
60 [[/[\w]+/, "variable"]]
61 ], closing);
62 }
63 return "variable-2";
64 }
65
66 var escaped = false;
67 // Normal string
68 while (!stream.eol() &&
69 (escaped || (!stream.match("{$", false) &&
70 !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
71 if (!escaped && stream.match(closing)) {
72 state.tokenize = null;
73 state.tokStack.pop(); state.tokStack.pop();
74 break;
75 }
76 escaped = stream.next() == "\\" && !escaped;
77 }
78 return "string";
79 }
80
81 var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
82 "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
83 "for foreach function global goto if implements interface instanceof namespace " +
84 "new or private protected public static switch throw trait try use var while xor " +
85 "die echo empty exit eval include include_once isset list require require_once return " +
86 "print unset __halt_compiler self static parent yield insteadof finally";
87 var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
88 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 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
90 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
91
92 var phpConfig = {
93 name: "clike",
94 helperType: "php",
95 keywords: keywords(phpKeywords),
96 blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
97 atoms: keywords(phpAtoms),
98 builtin: keywords(phpBuiltin),
99 multiLineStrings: true,
100 hooks: {
101 "$": function(stream) {
102 stream.eatWhile(/[\w\$_]/);
103 return "variable-2";
104 },
105 "<": function(stream, state) {
106 if (stream.match(/<</)) {
107 stream.eatWhile(/[\w\.]/);
108 var delim = stream.current().slice(3);
109 if (delim) {
110 (state.tokStack || (state.tokStack = [])).push(delim, 0);
111 state.tokenize = stringWithEscapes(delim);
112 return "string";
113 }
114 }
115 return false;
116 },
117 "#": function(stream) {
118 while (!stream.eol() && !stream.match("?>", false)) stream.next();
119 return "comment";
120 },
121 "/": function(stream) {
122 if (stream.eat("/")) {
123 while (!stream.eol() && !stream.match("?>", false)) stream.next();
124 return "comment";
125 }
126 return false;
127 },
128 '"': function(_stream, state) {
129 (state.tokStack || (state.tokStack = [])).push('"', 0);
130 state.tokenize = stringWithEscapes('"');
131 return "string";
132 },
133 "{": function(_stream, state) {
134 if (state.tokStack && state.tokStack.length)
135 state.tokStack[state.tokStack.length - 1]++;
136 return false;
137 },
138 "}": function(_stream, state) {
139 if (state.tokStack && state.tokStack.length > 0 &&
140 !--state.tokStack[state.tokStack.length - 1]) {
141 state.tokenize = stringWithEscapes(state.tokStack[state.tokStack.length - 2]);
142 }
143 return false;
144 }
145 }
146 };
147
148 CodeMirror.defineMode("php", function(config, parserConfig) {
149 var htmlMode = CodeMirror.getMode(config, "text/html");
150 var phpMode = CodeMirror.getMode(config, phpConfig);
151
152 function dispatch(stream, state) {
153 var isPHP = state.curMode == phpMode;
154 if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
155 if (!isPHP) {
156 if (stream.match(/^<\?\w*/)) {
157 state.curMode = phpMode;
158 state.curState = state.php;
159 return "meta";
160 }
161 if (state.pending == '"' || state.pending == "'") {
162 while (!stream.eol() && stream.next() != state.pending) {}
163 var style = "string";
164 } else if (state.pending && stream.pos < state.pending.end) {
165 stream.pos = state.pending.end;
166 var style = state.pending.style;
167 } else {
168 var style = htmlMode.token(stream, state.curState);
169 }
170 if (state.pending) state.pending = null;
171 var cur = stream.current(), openPHP = cur.search(/<\?/), m;
172 if (openPHP != -1) {
173 if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
174 else state.pending = {end: stream.pos, style: style};
175 stream.backUp(cur.length - openPHP);
176 }
177 return style;
178 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
179 state.curMode = htmlMode;
180 state.curState = state.html;
181 return "meta";
182 } else {
183 return phpMode.token(stream, state.curState);
184 }
185 }
186
187 return {
188 startState: function() {
189 var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
190 return {html: html,
191 php: php,
192 curMode: parserConfig.startOpen ? phpMode : htmlMode,
193 curState: parserConfig.startOpen ? php : html,
194 pending: null};
195 },
196
197 copyState: function(state) {
198 var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
199 php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
200 if (state.curMode == htmlMode) cur = htmlNew;
201 else cur = phpNew;
202 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
203 pending: state.pending};
204 },
205
206 token: dispatch,
207
208 indent: function(state, textAfter) {
209 if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
210 (state.curMode == phpMode && /^\?>/.test(textAfter)))
211 return htmlMode.indent(state.html, textAfter);
212 return state.curMode.indent(state.curState, textAfter);
213 },
214
215 blockCommentStart: "/*",
216 blockCommentEnd: "*/",
217 lineComment: "//",
218
219 innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
220 };
221 }, "htmlmixed", "clike");
222
223 CodeMirror.defineMIME("application/x-httpd-php", "php");
224 CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
225 CodeMirror.defineMIME("text/x-php", phpConfig);
226 });
@@ -1,188 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 * Pig Latin Mode for CodeMirror 2
6 * @author Prasanth Jayachandran
7 * @link https://github.com/prasanthj/pig-codemirror-2
8 * This implementation is adapted from PL/SQL mode in CodeMirror 2.
9 */
10 (function(mod) {
11 if (typeof exports == "object" && typeof module == "object") // CommonJS
12 mod(require("../../lib/codemirror"));
13 else if (typeof define == "function" && define.amd) // AMD
14 define(["../../lib/codemirror"], mod);
15 else // Plain browser env
16 mod(CodeMirror);
17 })(function(CodeMirror) {
18 "use strict";
19
20 CodeMirror.defineMode("pig", function(_config, parserConfig) {
21 var keywords = parserConfig.keywords,
22 builtins = parserConfig.builtins,
23 types = parserConfig.types,
24 multiLineStrings = parserConfig.multiLineStrings;
25
26 var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
27
28 function chain(stream, state, f) {
29 state.tokenize = f;
30 return f(stream, state);
31 }
32
33 var type;
34 function ret(tp, style) {
35 type = tp;
36 return style;
37 }
38
39 function tokenComment(stream, state) {
40 var isEnd = false;
41 var ch;
42 while(ch = stream.next()) {
43 if(ch == "/" && isEnd) {
44 state.tokenize = tokenBase;
45 break;
46 }
47 isEnd = (ch == "*");
48 }
49 return ret("comment", "comment");
50 }
51
52 function tokenString(quote) {
53 return function(stream, state) {
54 var escaped = false, next, end = false;
55 while((next = stream.next()) != null) {
56 if (next == quote && !escaped) {
57 end = true; break;
58 }
59 escaped = !escaped && next == "\\";
60 }
61 if (end || !(escaped || multiLineStrings))
62 state.tokenize = tokenBase;
63 return ret("string", "error");
64 };
65 }
66
67 function tokenBase(stream, state) {
68 var ch = stream.next();
69
70 // is a start of string?
71 if (ch == '"' || ch == "'")
72 return chain(stream, state, tokenString(ch));
73 // is it one of the special chars
74 else if(/[\[\]{}\(\),;\.]/.test(ch))
75 return ret(ch);
76 // is it a number?
77 else if(/\d/.test(ch)) {
78 stream.eatWhile(/[\w\.]/);
79 return ret("number", "number");
80 }
81 // multi line comment or operator
82 else if (ch == "/") {
83 if (stream.eat("*")) {
84 return chain(stream, state, tokenComment);
85 }
86 else {
87 stream.eatWhile(isOperatorChar);
88 return ret("operator", "operator");
89 }
90 }
91 // single line comment or operator
92 else if (ch=="-") {
93 if(stream.eat("-")){
94 stream.skipToEnd();
95 return ret("comment", "comment");
96 }
97 else {
98 stream.eatWhile(isOperatorChar);
99 return ret("operator", "operator");
100 }
101 }
102 // is it an operator
103 else if (isOperatorChar.test(ch)) {
104 stream.eatWhile(isOperatorChar);
105 return ret("operator", "operator");
106 }
107 else {
108 // get the while word
109 stream.eatWhile(/[\w\$_]/);
110 // is it one of the listed keywords?
111 if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
112 if (stream.eat(")") || stream.eat(".")) {
113 //keywords can be used as variables like flatten(group), group.$0 etc..
114 }
115 else {
116 return ("keyword", "keyword");
117 }
118 }
119 // is it one of the builtin functions?
120 if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
121 {
122 return ("keyword", "variable-2");
123 }
124 // is it one of the listed types?
125 if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
126 return ("keyword", "variable-3");
127 // default is a 'variable'
128 return ret("variable", "pig-word");
129 }
130 }
131
132 // Interface
133 return {
134 startState: function() {
135 return {
136 tokenize: tokenBase,
137 startOfLine: true
138 };
139 },
140
141 token: function(stream, state) {
142 if(stream.eatSpace()) return null;
143 var style = state.tokenize(stream, state);
144 return style;
145 }
146 };
147 });
148
149 (function() {
150 function keywords(str) {
151 var obj = {}, words = str.split(" ");
152 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
153 return obj;
154 }
155
156 // builtin funcs taken from trunk revision 1303237
157 var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
158 + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
159 + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
160 + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
161 + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
162 + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
163 + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
164 + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
165 + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
166 + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
167
168 // taken from QueryLexer.g
169 var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
170 + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
171 + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
172 + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
173 + "NEQ MATCHES TRUE FALSE DUMP";
174
175 // data types
176 var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP ";
177
178 CodeMirror.defineMIME("text/x-pig", {
179 name: "pig",
180 builtins: keywords(pBuiltins),
181 keywords: keywords(pKeywords),
182 types: keywords(pTypes)
183 });
184
185 CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
186 }());
187
188 });
@@ -1,78 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("properties", function() {
15 return {
16 token: function(stream, state) {
17 var sol = stream.sol() || state.afterSection;
18 var eol = stream.eol();
19
20 state.afterSection = false;
21
22 if (sol) {
23 if (state.nextMultiline) {
24 state.inMultiline = true;
25 state.nextMultiline = false;
26 } else {
27 state.position = "def";
28 }
29 }
30
31 if (eol && ! state.nextMultiline) {
32 state.inMultiline = false;
33 state.position = "def";
34 }
35
36 if (sol) {
37 while(stream.eatSpace());
38 }
39
40 var ch = stream.next();
41
42 if (sol && (ch === "#" || ch === "!" || ch === ";")) {
43 state.position = "comment";
44 stream.skipToEnd();
45 return "comment";
46 } else if (sol && ch === "[") {
47 state.afterSection = true;
48 stream.skipTo("]"); stream.eat("]");
49 return "header";
50 } else if (ch === "=" || ch === ":") {
51 state.position = "quote";
52 return null;
53 } else if (ch === "\\" && state.position === "quote") {
54 if (stream.next() !== "u") { // u = Unicode sequence \u1234
55 // Multiline value
56 state.nextMultiline = true;
57 }
58 }
59
60 return state.position;
61 },
62
63 startState: function() {
64 return {
65 position : "def", // Current position, "def", "quote" or "comment"
66 nextMultiline : false, // Is the next line multiline value
67 inMultiline : false, // Is the current line a multiline value
68 afterSection : false // Did we just open a section
69 };
70 }
71
72 };
73 });
74
75 CodeMirror.defineMIME("text/x-properties", "properties");
76 CodeMirror.defineMIME("text/x-ini", "properties");
77
78 });
@@ -1,220 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("puppet", function () {
15 // Stores the words from the define method
16 var words = {};
17 // Taken, mostly, from the Puppet official variable standards regex
18 var variable_regex = /({)?([a-z][a-z0-9_]*)?((::[a-z][a-z0-9_]*)*::)?[a-zA-Z0-9_]+(})?/;
19
20 // Takes a string of words separated by spaces and adds them as
21 // keys with the value of the first argument 'style'
22 function define(style, string) {
23 var split = string.split(' ');
24 for (var i = 0; i < split.length; i++) {
25 words[split[i]] = style;
26 }
27 }
28
29 // Takes commonly known puppet types/words and classifies them to a style
30 define('keyword', 'class define site node include import inherits');
31 define('keyword', 'case if else in and elsif default or');
32 define('atom', 'false true running present absent file directory undef');
33 define('builtin', 'action augeas burst chain computer cron destination dport exec ' +
34 'file filebucket group host icmp iniface interface jump k5login limit log_level ' +
35 'log_prefix macauthorization mailalias maillist mcx mount nagios_command ' +
36 'nagios_contact nagios_contactgroup nagios_host nagios_hostdependency ' +
37 'nagios_hostescalation nagios_hostextinfo nagios_hostgroup nagios_service ' +
38 'nagios_servicedependency nagios_serviceescalation nagios_serviceextinfo ' +
39 'nagios_servicegroup nagios_timeperiod name notify outiface package proto reject ' +
40 'resources router schedule scheduled_task selboolean selmodule service source ' +
41 'sport ssh_authorized_key sshkey stage state table tidy todest toports tosource ' +
42 'user vlan yumrepo zfs zone zpool');
43
44 // After finding a start of a string ('|") this function attempts to find the end;
45 // If a variable is encountered along the way, we display it differently when it
46 // is encapsulated in a double-quoted string.
47 function tokenString(stream, state) {
48 var current, prev, found_var = false;
49 while (!stream.eol() && (current = stream.next()) != state.pending) {
50 if (current === '$' && prev != '\\' && state.pending == '"') {
51 found_var = true;
52 break;
53 }
54 prev = current;
55 }
56 if (found_var) {
57 stream.backUp(1);
58 }
59 if (current == state.pending) {
60 state.continueString = false;
61 } else {
62 state.continueString = true;
63 }
64 return "string";
65 }
66
67 // Main function
68 function tokenize(stream, state) {
69 // Matches one whole word
70 var word = stream.match(/[\w]+/, false);
71 // Matches attributes (i.e. ensure => present ; 'ensure' would be matched)
72 var attribute = stream.match(/(\s+)?\w+\s+=>.*/, false);
73 // Matches non-builtin resource declarations
74 // (i.e. "apache::vhost {" or "mycustomclasss {" would be matched)
75 var resource = stream.match(/(\s+)?[\w:_]+(\s+)?{/, false);
76 // Matches virtual and exported resources (i.e. @@user { ; and the like)
77 var special_resource = stream.match(/(\s+)?[@]{1,2}[\w:_]+(\s+)?{/, false);
78
79 // Finally advance the stream
80 var ch = stream.next();
81
82 // Have we found a variable?
83 if (ch === '$') {
84 if (stream.match(variable_regex)) {
85 // If so, and its in a string, assign it a different color
86 return state.continueString ? 'variable-2' : 'variable';
87 }
88 // Otherwise return an invalid variable
89 return "error";
90 }
91 // Should we still be looking for the end of a string?
92 if (state.continueString) {
93 // If so, go through the loop again
94 stream.backUp(1);
95 return tokenString(stream, state);
96 }
97 // Are we in a definition (class, node, define)?
98 if (state.inDefinition) {
99 // If so, return def (i.e. for 'class myclass {' ; 'myclass' would be matched)
100 if (stream.match(/(\s+)?[\w:_]+(\s+)?/)) {
101 return 'def';
102 }
103 // Match the rest it the next time around
104 stream.match(/\s+{/);
105 state.inDefinition = false;
106 }
107 // Are we in an 'include' statement?
108 if (state.inInclude) {
109 // Match and return the included class
110 stream.match(/(\s+)?\S+(\s+)?/);
111 state.inInclude = false;
112 return 'def';
113 }
114 // Do we just have a function on our hands?
115 // In 'ensure_resource("myclass")', 'ensure_resource' is matched
116 if (stream.match(/(\s+)?\w+\(/)) {
117 stream.backUp(1);
118 return 'def';
119 }
120 // Have we matched the prior attribute regex?
121 if (attribute) {
122 stream.match(/(\s+)?\w+/);
123 return 'tag';
124 }
125 // Do we have Puppet specific words?
126 if (word && words.hasOwnProperty(word)) {
127 // Negates the initial next()
128 stream.backUp(1);
129 // Acutally move the stream
130 stream.match(/[\w]+/);
131 // We want to process these words differently
132 // do to the importance they have in Puppet
133 if (stream.match(/\s+\S+\s+{/, false)) {
134 state.inDefinition = true;
135 }
136 if (word == 'include') {
137 state.inInclude = true;
138 }
139 // Returns their value as state in the prior define methods
140 return words[word];
141 }
142 // Is there a match on a reference?
143 if (/(\s+)?[A-Z]/.test(word)) {
144 // Negate the next()
145 stream.backUp(1);
146 // Match the full reference
147 stream.match(/(\s+)?[A-Z][\w:_]+/);
148 return 'def';
149 }
150 // Have we matched the prior resource regex?
151 if (resource) {
152 stream.match(/(\s+)?[\w:_]+/);
153 return 'def';
154 }
155 // Have we matched the prior special_resource regex?
156 if (special_resource) {
157 stream.match(/(\s+)?[@]{1,2}/);
158 return 'special';
159 }
160 // Match all the comments. All of them.
161 if (ch == "#") {
162 stream.skipToEnd();
163 return "comment";
164 }
165 // Have we found a string?
166 if (ch == "'" || ch == '"') {
167 // Store the type (single or double)
168 state.pending = ch;
169 // Perform the looping function to find the end
170 return tokenString(stream, state);
171 }
172 // Match all the brackets
173 if (ch == '{' || ch == '}') {
174 return 'bracket';
175 }
176 // Match characters that we are going to assume
177 // are trying to be regex
178 if (ch == '/') {
179 stream.match(/.*?\//);
180 return 'variable-3';
181 }
182 // Match all the numbers
183 if (ch.match(/[0-9]/)) {
184 stream.eatWhile(/[0-9]+/);
185 return 'number';
186 }
187 // Match the '=' and '=>' operators
188 if (ch == '=') {
189 if (stream.peek() == '>') {
190 stream.next();
191 }
192 return "operator";
193 }
194 // Keep advancing through all the rest
195 stream.eatWhile(/[\w-]/);
196 // Return a blank line for everything else
197 return null;
198 }
199 // Start it all
200 return {
201 startState: function () {
202 var state = {};
203 state.inDefinition = false;
204 state.inInclude = false;
205 state.continueString = false;
206 state.pending = false;
207 return state;
208 },
209 token: function (stream, state) {
210 // Strip the spaces, but regex will account for them eitherway
211 if (stream.eatSpace()) return null;
212 // Go through the main process
213 return tokenize(stream, state);
214 }
215 };
216 });
217
218 CodeMirror.defineMIME("text/x-puppet", "puppet");
219
220 });
@@ -1,359 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 function wordRegexp(words) {
15 return new RegExp("^((" + words.join(")|(") + "))\\b");
16 }
17
18 var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19 var commonKeywords = ["as", "assert", "break", "class", "continue",
20 "def", "del", "elif", "else", "except", "finally",
21 "for", "from", "global", "if", "import",
22 "lambda", "pass", "raise", "return",
23 "try", "while", "with", "yield", "in"];
24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 "enumerate", "eval", "filter", "float", "format", "frozenset",
27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 "input", "int", "isinstance", "issubclass", "iter", "len",
29 "list", "locals", "map", "max", "memoryview", "min", "next",
30 "object", "oct", "open", "ord", "pow", "property", "range",
31 "repr", "reversed", "round", "set", "setattr", "slice",
32 "sorted", "staticmethod", "str", "sum", "super", "tuple",
33 "type", "vars", "zip", "__import__", "NotImplemented",
34 "Ellipsis", "__debug__"];
35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
36 "file", "intern", "long", "raw_input", "reduce", "reload",
37 "unichr", "unicode", "xrange", "False", "True", "None"],
38 keywords: ["exec", "print"]};
39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
40 keywords: ["nonlocal", "False", "True", "None"]};
41
42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
43
44 function top(state) {
45 return state.scopes[state.scopes.length - 1];
46 }
47
48 CodeMirror.defineMode("python", function(conf, parserConf) {
49 var ERRORCLASS = "error";
50
51 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
52 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
53 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
54 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
55
56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
58 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
59 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
60 } else {
61 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
62 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
63 }
64
65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
66
67 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
68 if(parserConf.extra_keywords != undefined){
69 myKeywords = myKeywords.concat(parserConf.extra_keywords);
70 }
71 if(parserConf.extra_builtins != undefined){
72 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
73 }
74 if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
75 myKeywords = myKeywords.concat(py3.keywords);
76 myBuiltins = myBuiltins.concat(py3.builtins);
77 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
78 } else {
79 myKeywords = myKeywords.concat(py2.keywords);
80 myBuiltins = myBuiltins.concat(py2.builtins);
81 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
82 }
83 var keywords = wordRegexp(myKeywords);
84 var builtins = wordRegexp(myBuiltins);
85
86 // tokenizers
87 function tokenBase(stream, state) {
88 // Handle scope changes
89 if (stream.sol() && top(state).type == "py") {
90 var scopeOffset = top(state).offset;
91 if (stream.eatSpace()) {
92 var lineOffset = stream.indentation();
93 if (lineOffset > scopeOffset)
94 pushScope(stream, state, "py");
95 else if (lineOffset < scopeOffset && dedent(stream, state))
96 state.errorToken = true;
97 return null;
98 } else {
99 var style = tokenBaseInner(stream, state);
100 if (scopeOffset > 0 && dedent(stream, state))
101 style += " " + ERRORCLASS;
102 return style;
103 }
104 }
105 return tokenBaseInner(stream, state);
106 }
107
108 function tokenBaseInner(stream, state) {
109 if (stream.eatSpace()) return null;
110
111 var ch = stream.peek();
112
113 // Handle Comments
114 if (ch == "#") {
115 stream.skipToEnd();
116 return "comment";
117 }
118
119 // Handle Number Literals
120 if (stream.match(/^[0-9\.]/, false)) {
121 var floatLiteral = false;
122 // Floats
123 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
124 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
125 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
126 if (floatLiteral) {
127 // Float literals may be "imaginary"
128 stream.eat(/J/i);
129 return "number";
130 }
131 // Integers
132 var intLiteral = false;
133 // Hex
134 if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
135 // Binary
136 if (stream.match(/^0b[01]+/i)) intLiteral = true;
137 // Octal
138 if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
139 // Decimal
140 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
141 // Decimal literals may be "imaginary"
142 stream.eat(/J/i);
143 // TODO - Can you have imaginary longs?
144 intLiteral = true;
145 }
146 // Zero by itself with no other piece of number.
147 if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
148 if (intLiteral) {
149 // Integer literals may be "long"
150 stream.eat(/L/i);
151 return "number";
152 }
153 }
154
155 // Handle Strings
156 if (stream.match(stringPrefixes)) {
157 state.tokenize = tokenStringFactory(stream.current());
158 return state.tokenize(stream, state);
159 }
160
161 // Handle operators and Delimiters
162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
163 return null;
164
165 if (stream.match(doubleOperators)
166 || stream.match(singleOperators)
167 || stream.match(wordOperators))
168 return "operator";
169
170 if (stream.match(singleDelimiters))
171 return null;
172
173 if (stream.match(keywords))
174 return "keyword";
175
176 if (stream.match(builtins))
177 return "builtin";
178
179 if (stream.match(/^(self|cls)\b/))
180 return "variable-2";
181
182 if (stream.match(identifiers)) {
183 if (state.lastToken == "def" || state.lastToken == "class")
184 return "def";
185 return "variable";
186 }
187
188 // Handle non-detected items
189 stream.next();
190 return ERRORCLASS;
191 }
192
193 function tokenStringFactory(delimiter) {
194 while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
195 delimiter = delimiter.substr(1);
196
197 var singleline = delimiter.length == 1;
198 var OUTCLASS = "string";
199
200 function tokenString(stream, state) {
201 while (!stream.eol()) {
202 stream.eatWhile(/[^'"\\]/);
203 if (stream.eat("\\")) {
204 stream.next();
205 if (singleline && stream.eol())
206 return OUTCLASS;
207 } else if (stream.match(delimiter)) {
208 state.tokenize = tokenBase;
209 return OUTCLASS;
210 } else {
211 stream.eat(/['"]/);
212 }
213 }
214 if (singleline) {
215 if (parserConf.singleLineStringErrors)
216 return ERRORCLASS;
217 else
218 state.tokenize = tokenBase;
219 }
220 return OUTCLASS;
221 }
222 tokenString.isString = true;
223 return tokenString;
224 }
225
226 function pushScope(stream, state, type) {
227 var offset = 0, align = null;
228 if (type == "py") {
229 while (top(state).type != "py")
230 state.scopes.pop();
231 }
232 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent);
233 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
234 align = stream.column() + 1;
235 state.scopes.push({offset: offset, type: type, align: align});
236 }
237
238 function dedent(stream, state) {
239 var indented = stream.indentation();
240 while (top(state).offset > indented) {
241 if (top(state).type != "py") return true;
242 state.scopes.pop();
243 }
244 return top(state).offset != indented;
245 }
246
247 function tokenLexer(stream, state) {
248 var style = state.tokenize(stream, state);
249 var current = stream.current();
250
251 // Handle '.' connected identifiers
252 if (current == ".") {
253 style = stream.match(identifiers, false) ? null : ERRORCLASS;
254 if (style == null && state.lastStyle == "meta") {
255 // Apply 'meta' style to '.' connected identifiers when
256 // appropriate.
257 style = "meta";
258 }
259 return style;
260 }
261
262 // Handle decorators
263 if (current == "@"){
264 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
265 return stream.match(identifiers, false) ? "meta" : "operator";
266 } else {
267 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
268 }
269 }
270
271 if ((style == "variable" || style == "builtin")
272 && state.lastStyle == "meta")
273 style = "meta";
274
275 // Handle scope changes.
276 if (current == "pass" || current == "return")
277 state.dedent += 1;
278
279 if (current == "lambda") state.lambda = true;
280 if (current == ":" && !state.lambda && top(state).type == "py")
281 pushScope(stream, state, "py");
282
283 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
284 if (delimiter_index != -1)
285 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
286
287 delimiter_index = "])}".indexOf(current);
288 if (delimiter_index != -1) {
289 if (top(state).type == current) state.scopes.pop();
290 else return ERRORCLASS;
291 }
292 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
293 if (state.scopes.length > 1) state.scopes.pop();
294 state.dedent -= 1;
295 }
296
297 return style;
298 }
299
300 var external = {
301 startState: function(basecolumn) {
302 return {
303 tokenize: tokenBase,
304 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
305 lastStyle: null,
306 lastToken: null,
307 lambda: false,
308 dedent: 0
309 };
310 },
311
312 token: function(stream, state) {
313 var addErr = state.errorToken;
314 if (addErr) state.errorToken = false;
315 var style = tokenLexer(stream, state);
316
317 state.lastStyle = style;
318
319 var current = stream.current();
320 if (current && style)
321 state.lastToken = current;
322
323 if (stream.eol() && state.lambda)
324 state.lambda = false;
325 return addErr ? style + " " + ERRORCLASS : style;
326 },
327
328 indent: function(state, textAfter) {
329 if (state.tokenize != tokenBase)
330 return state.tokenize.isString ? CodeMirror.Pass : 0;
331
332 var scope = top(state);
333 var closing = textAfter && textAfter.charAt(0) == scope.type;
334 if (scope.align != null)
335 return scope.align - (closing ? 1 : 0);
336 else if (closing && state.scopes.length > 1)
337 return state.scopes[state.scopes.length - 2].offset;
338 else
339 return scope.offset;
340 },
341
342 lineComment: "#",
343 fold: "indent"
344 };
345 return external;
346 });
347
348 CodeMirror.defineMIME("text/x-python", "python");
349
350 var words = function(str) { return str.split(" "); };
351
352 CodeMirror.defineMIME("text/x-cython", {
353 name: "python",
354 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
355 "extern gil include nogil property public"+
356 "readonly struct union DEF IF ELIF ELSE")
357 });
358
359 });
@@ -1,139 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("q",function(config){
15 var indentUnit=config.indentUnit,
16 curPunc,
17 keywords=buildRE(["abs","acos","aj","aj0","all","and","any","asc","asin","asof","atan","attr","avg","avgs","bin","by","ceiling","cols","cor","cos","count","cov","cross","csv","cut","delete","deltas","desc","dev","differ","distinct","div","do","each","ej","enlist","eval","except","exec","exit","exp","fby","fills","first","fkeys","flip","floor","from","get","getenv","group","gtime","hclose","hcount","hdel","hopen","hsym","iasc","idesc","if","ij","in","insert","inter","inv","key","keys","last","like","list","lj","load","log","lower","lsq","ltime","ltrim","mavg","max","maxs","mcount","md5","mdev","med","meta","min","mins","mmax","mmin","mmu","mod","msum","neg","next","not","null","or","over","parse","peach","pj","plist","prd","prds","prev","prior","rand","rank","ratios","raze","read0","read1","reciprocal","reverse","rload","rotate","rsave","rtrim","save","scan","select","set","setenv","show","signum","sin","sqrt","ss","ssr","string","sublist","sum","sums","sv","system","tables","tan","til","trim","txf","type","uj","ungroup","union","update","upper","upsert","value","var","view","views","vs","wavg","where","where","while","within","wj","wj1","wsum","xasc","xbar","xcol","xcols","xdesc","xexp","xgroup","xkey","xlog","xprev","xrank"]),
18 E=/[|/&^!+:\\\-*%$=~#;@><,?_\'\"\[\(\]\)\s{}]/;
19 function buildRE(w){return new RegExp("^("+w.join("|")+")$");}
20 function tokenBase(stream,state){
21 var sol=stream.sol(),c=stream.next();
22 curPunc=null;
23 if(sol)
24 if(c=="/")
25 return(state.tokenize=tokenLineComment)(stream,state);
26 else if(c=="\\"){
27 if(stream.eol()||/\s/.test(stream.peek()))
28 return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream, state):state.tokenize=tokenBase,"comment";
29 else
30 return state.tokenize=tokenBase,"builtin";
31 }
32 if(/\s/.test(c))
33 return stream.peek()=="/"?(stream.skipToEnd(),"comment"):"whitespace";
34 if(c=='"')
35 return(state.tokenize=tokenString)(stream,state);
36 if(c=='`')
37 return stream.eatWhile(/[A-Z|a-z|\d|_|:|\/|\.]/),"symbol";
38 if(("."==c&&/\d/.test(stream.peek()))||/\d/.test(c)){
39 var t=null;
40 stream.backUp(1);
41 if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([D|T](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
42 || stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/)
43 || stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/)
44 || stream.match(/^\d+[ptuv]{1}/))
45 t="temporal";
46 else if(stream.match(/^0[NwW]{1}/)
47 || stream.match(/^0x[\d|a-f|A-F]*/)
48 || stream.match(/^[0|1]+[b]{1}/)
49 || stream.match(/^\d+[chijn]{1}/)
50 || stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/))
51 t="number";
52 return(t&&(!(c=stream.peek())||E.test(c)))?t:(stream.next(),"error");
53 }
54 if(/[A-Z|a-z]|\./.test(c))
55 return stream.eatWhile(/[A-Z|a-z|\.|_|\d]/),keywords.test(stream.current())?"keyword":"variable";
56 if(/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c))
57 return null;
58 if(/[{}\(\[\]\)]/.test(c))
59 return null;
60 return"error";
61 }
62 function tokenLineComment(stream,state){
63 return stream.skipToEnd(),/\/\s*$/.test(stream.current())?(state.tokenize=tokenBlockComment)(stream,state):(state.tokenize=tokenBase),"comment";
64 }
65 function tokenBlockComment(stream,state){
66 var f=stream.sol()&&stream.peek()=="\\";
67 stream.skipToEnd();
68 if(f&&/^\\\s*$/.test(stream.current()))
69 state.tokenize=tokenBase;
70 return"comment";
71 }
72 function tokenCommentToEOF(stream){return stream.skipToEnd(),"comment";}
73 function tokenString(stream,state){
74 var escaped=false,next,end=false;
75 while((next=stream.next())){
76 if(next=="\""&&!escaped){end=true;break;}
77 escaped=!escaped&&next=="\\";
78 }
79 if(end)state.tokenize=tokenBase;
80 return"string";
81 }
82 function pushContext(state,type,col){state.context={prev:state.context,indent:state.indent,col:col,type:type};}
83 function popContext(state){state.indent=state.context.indent;state.context=state.context.prev;}
84 return{
85 startState:function(){
86 return{tokenize:tokenBase,
87 context:null,
88 indent:0,
89 col:0};
90 },
91 token:function(stream,state){
92 if(stream.sol()){
93 if(state.context&&state.context.align==null)
94 state.context.align=false;
95 state.indent=stream.indentation();
96 }
97 //if (stream.eatSpace()) return null;
98 var style=state.tokenize(stream,state);
99 if(style!="comment"&&state.context&&state.context.align==null&&state.context.type!="pattern"){
100 state.context.align=true;
101 }
102 if(curPunc=="(")pushContext(state,")",stream.column());
103 else if(curPunc=="[")pushContext(state,"]",stream.column());
104 else if(curPunc=="{")pushContext(state,"}",stream.column());
105 else if(/[\]\}\)]/.test(curPunc)){
106 while(state.context&&state.context.type=="pattern")popContext(state);
107 if(state.context&&curPunc==state.context.type)popContext(state);
108 }
109 else if(curPunc=="."&&state.context&&state.context.type=="pattern")popContext(state);
110 else if(/atom|string|variable/.test(style)&&state.context){
111 if(/[\}\]]/.test(state.context.type))
112 pushContext(state,"pattern",stream.column());
113 else if(state.context.type=="pattern"&&!state.context.align){
114 state.context.align=true;
115 state.context.col=stream.column();
116 }
117 }
118 return style;
119 },
120 indent:function(state,textAfter){
121 var firstChar=textAfter&&textAfter.charAt(0);
122 var context=state.context;
123 if(/[\]\}]/.test(firstChar))
124 while (context&&context.type=="pattern")context=context.prev;
125 var closing=context&&firstChar==context.type;
126 if(!context)
127 return 0;
128 else if(context.type=="pattern")
129 return context.col;
130 else if(context.align)
131 return context.col+(closing?0:1);
132 else
133 return context.indent+(closing?0:indentUnit);
134 }
135 };
136 });
137 CodeMirror.defineMIME("text/x-q","q");
138
139 });
@@ -1,162 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("r", function(config) {
15 function wordObj(str) {
16 var words = str.split(" "), res = {};
17 for (var i = 0; i < words.length; ++i) res[words[i]] = true;
18 return res;
19 }
20 var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");
21 var builtins = wordObj("list quote bquote eval return call parse deparse");
22 var keywords = wordObj("if else repeat while function for in next break");
23 var blockkeywords = wordObj("if else repeat while function for");
24 var opChars = /[+\-*\/^<>=!&|~$:]/;
25 var curPunc;
26
27 function tokenBase(stream, state) {
28 curPunc = null;
29 var ch = stream.next();
30 if (ch == "#") {
31 stream.skipToEnd();
32 return "comment";
33 } else if (ch == "0" && stream.eat("x")) {
34 stream.eatWhile(/[\da-f]/i);
35 return "number";
36 } else if (ch == "." && stream.eat(/\d/)) {
37 stream.match(/\d*(?:e[+\-]?\d+)?/);
38 return "number";
39 } else if (/\d/.test(ch)) {
40 stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
41 return "number";
42 } else if (ch == "'" || ch == '"') {
43 state.tokenize = tokenString(ch);
44 return "string";
45 } else if (ch == "." && stream.match(/.[.\d]+/)) {
46 return "keyword";
47 } else if (/[\w\.]/.test(ch) && ch != "_") {
48 stream.eatWhile(/[\w\.]/);
49 var word = stream.current();
50 if (atoms.propertyIsEnumerable(word)) return "atom";
51 if (keywords.propertyIsEnumerable(word)) {
52 // Block keywords start new blocks, except 'else if', which only starts
53 // one new block for the 'if', no block for the 'else'.
54 if (blockkeywords.propertyIsEnumerable(word) &&
55 !stream.match(/\s*if(\s+|$)/, false))
56 curPunc = "block";
57 return "keyword";
58 }
59 if (builtins.propertyIsEnumerable(word)) return "builtin";
60 return "variable";
61 } else if (ch == "%") {
62 if (stream.skipTo("%")) stream.next();
63 return "variable-2";
64 } else if (ch == "<" && stream.eat("-")) {
65 return "arrow";
66 } else if (ch == "=" && state.ctx.argList) {
67 return "arg-is";
68 } else if (opChars.test(ch)) {
69 if (ch == "$") return "dollar";
70 stream.eatWhile(opChars);
71 return "operator";
72 } else if (/[\(\){}\[\];]/.test(ch)) {
73 curPunc = ch;
74 if (ch == ";") return "semi";
75 return null;
76 } else {
77 return null;
78 }
79 }
80
81 function tokenString(quote) {
82 return function(stream, state) {
83 if (stream.eat("\\")) {
84 var ch = stream.next();
85 if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
86 else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
87 else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
88 else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
89 else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
90 return "string-2";
91 } else {
92 var next;
93 while ((next = stream.next()) != null) {
94 if (next == quote) { state.tokenize = tokenBase; break; }
95 if (next == "\\") { stream.backUp(1); break; }
96 }
97 return "string";
98 }
99 };
100 }
101
102 function push(state, type, stream) {
103 state.ctx = {type: type,
104 indent: state.indent,
105 align: null,
106 column: stream.column(),
107 prev: state.ctx};
108 }
109 function pop(state) {
110 state.indent = state.ctx.indent;
111 state.ctx = state.ctx.prev;
112 }
113
114 return {
115 startState: function() {
116 return {tokenize: tokenBase,
117 ctx: {type: "top",
118 indent: -config.indentUnit,
119 align: false},
120 indent: 0,
121 afterIdent: false};
122 },
123
124 token: function(stream, state) {
125 if (stream.sol()) {
126 if (state.ctx.align == null) state.ctx.align = false;
127 state.indent = stream.indentation();
128 }
129 if (stream.eatSpace()) return null;
130 var style = state.tokenize(stream, state);
131 if (style != "comment" && state.ctx.align == null) state.ctx.align = true;
132
133 var ctype = state.ctx.type;
134 if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);
135 if (curPunc == "{") push(state, "}", stream);
136 else if (curPunc == "(") {
137 push(state, ")", stream);
138 if (state.afterIdent) state.ctx.argList = true;
139 }
140 else if (curPunc == "[") push(state, "]", stream);
141 else if (curPunc == "block") push(state, "block", stream);
142 else if (curPunc == ctype) pop(state);
143 state.afterIdent = style == "variable" || style == "keyword";
144 return style;
145 },
146
147 indent: function(state, textAfter) {
148 if (state.tokenize != tokenBase) return 0;
149 var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
150 closing = firstChar == ctx.type;
151 if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
152 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
153 else return ctx.indent + (closing ? 0 : config.indentUnit);
154 },
155
156 lineComment: "#"
157 };
158 });
159
160 CodeMirror.defineMIME("text/x-rsrc", "r");
161
162 });
@@ -1,101 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("rpm-changes", function() {
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} - /;
17 var simpleEmail = /^[\w+.-]+@[\w.-]+/;
18
19 return {
20 token: function(stream) {
21 if (stream.sol()) {
22 if (stream.match(headerSeperator)) { return 'tag'; }
23 if (stream.match(headerLine)) { return 'tag'; }
24 }
25 if (stream.match(simpleEmail)) { return 'string'; }
26 stream.next();
27 return null;
28 }
29 };
30 });
31
32 CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
33
34 // Quick and dirty spec file highlighting
35
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)/;
38
39 var preamble = /^(Name|Version|Release|License|Summary|Url|Group|Source|BuildArch|BuildRequires|BuildRoot|AutoReqProv|Provides|Requires(\(\w+\))?|Obsoletes|Conflicts|Recommends|Source\d*|Patch\d*|ExclusiveArch|NoSource|Supplements):/;
40 var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pre|post|triggerin|triggerun|pretrans|posttrans|verifyscript|check|triggerpostun|triggerprein|trigger)/;
41 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
44
45 return {
46 startState: function () {
47 return {
48 controlFlow: false,
49 macroParameters: false,
50 section: false
51 };
52 },
53 token: function (stream, state) {
54 var ch = stream.peek();
55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
56
57 if (stream.sol()) {
58 if (stream.match(preamble)) { return "preamble"; }
59 if (stream.match(section)) { return "section"; }
60 }
61
62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
63 if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
64
65 if (stream.match(control_flow_simple)) { return "keyword"; }
66 if (stream.match(control_flow_complex)) {
67 state.controlFlow = true;
68 return "keyword";
69 }
70 if (state.controlFlow) {
71 if (stream.match(operators)) { return "operator"; }
72 if (stream.match(/^(\d+)/)) { return "number"; }
73 if (stream.eol()) { state.controlFlow = false; }
74 }
75
76 if (stream.match(arch)) { return "number"; }
77
78 // Macros like '%make_install' or '%attr(0775,root,root)'
79 if (stream.match(/^%[\w]+/)) {
80 if (stream.match(/^\(/)) { state.macroParameters = true; }
81 return "macro";
82 }
83 if (state.macroParameters) {
84 if (stream.match(/^\d+/)) { return "number";}
85 if (stream.match(/^\)/)) {
86 state.macroParameters = false;
87 return "macro";
88 }
89 }
90 if (stream.match(/^%\{\??[\w \-]+\}/)) { return "macro"; } // Macros like '%{defined fedora}'
91
92 //TODO: Include bash script sub-parser (CodeMirror supports that)
93 stream.next();
94 return null;
95 }
96 };
97 });
98
99 CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
100
101 });
This diff has been collapsed as it changes many lines, (557 lines changed) Show them Hide them
@@ -1,557 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('rst', function (config, options) {
15
16 var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
17 var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;
18 var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;
19
20 var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
21 var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
22 var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
23
24 var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
25 var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
26 var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
27 var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path);
28
29 var overlay = {
30 token: function (stream) {
31
32 if (stream.match(rx_strong) && stream.match (/\W+|$/, false))
33 return 'strong';
34 if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))
35 return 'em';
36 if (stream.match(rx_literal) && stream.match (/\W+|$/, false))
37 return 'string-2';
38 if (stream.match(rx_number))
39 return 'number';
40 if (stream.match(rx_positive))
41 return 'positive';
42 if (stream.match(rx_negative))
43 return 'negative';
44 if (stream.match(rx_uri))
45 return 'link';
46
47 while (stream.next() != null) {
48 if (stream.match(rx_strong, false)) break;
49 if (stream.match(rx_emphasis, false)) break;
50 if (stream.match(rx_literal, false)) break;
51 if (stream.match(rx_number, false)) break;
52 if (stream.match(rx_positive, false)) break;
53 if (stream.match(rx_negative, false)) break;
54 if (stream.match(rx_uri, false)) break;
55 }
56
57 return null;
58 }
59 };
60
61 var mode = CodeMirror.getMode(
62 config, options.backdrop || 'rst-base'
63 );
64
65 return CodeMirror.overlayMode(mode, overlay, true); // combine
66 }, 'python', 'stex');
67
68 ///////////////////////////////////////////////////////////////////////////////
69 ///////////////////////////////////////////////////////////////////////////////
70
71 CodeMirror.defineMode('rst-base', function (config) {
72
73 ///////////////////////////////////////////////////////////////////////////
74 ///////////////////////////////////////////////////////////////////////////
75
76 function format(string) {
77 var args = Array.prototype.slice.call(arguments, 1);
78 return string.replace(/{(\d+)}/g, function (match, n) {
79 return typeof args[n] != 'undefined' ? args[n] : match;
80 });
81 }
82
83 ///////////////////////////////////////////////////////////////////////////
84 ///////////////////////////////////////////////////////////////////////////
85
86 var mode_python = CodeMirror.getMode(config, 'python');
87 var mode_stex = CodeMirror.getMode(config, 'stex');
88
89 ///////////////////////////////////////////////////////////////////////////
90 ///////////////////////////////////////////////////////////////////////////
91
92 var SEPA = "\\s+";
93 var TAIL = "(?:\\s*|\\W|$)",
94 rx_TAIL = new RegExp(format('^{0}', TAIL));
95
96 var NAME =
97 "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",
98 rx_NAME = new RegExp(format('^{0}', NAME));
99 var NAME_WWS =
100 "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";
101 var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
102
103 var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
104 var TEXT2 = "(?:[^\\`]+)",
105 rx_TEXT2 = new RegExp(format('^{0}', TEXT2));
106
107 var rx_section = new RegExp(
108 "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$");
109 var rx_explicit = new RegExp(
110 format('^\\.\\.{0}', SEPA));
111 var rx_link = new RegExp(
112 format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL));
113 var rx_directive = new RegExp(
114 format('^{0}::{1}', REF_NAME, TAIL));
115 var rx_substitution = new RegExp(
116 format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL));
117 var rx_footnote = new RegExp(
118 format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL));
119 var rx_citation = new RegExp(
120 format('^\\[{0}\\]{1}', REF_NAME, TAIL));
121
122 var rx_substitution_ref = new RegExp(
123 format('^\\|{0}\\|', TEXT1));
124 var rx_footnote_ref = new RegExp(
125 format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME));
126 var rx_citation_ref = new RegExp(
127 format('^\\[{0}\\]_', REF_NAME));
128 var rx_link_ref1 = new RegExp(
129 format('^{0}__?', REF_NAME));
130 var rx_link_ref2 = new RegExp(
131 format('^`{0}`_', TEXT2));
132
133 var rx_role_pre = new RegExp(
134 format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL));
135 var rx_role_suf = new RegExp(
136 format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL));
137 var rx_role = new RegExp(
138 format('^:{0}:{1}', NAME, TAIL));
139
140 var rx_directive_name = new RegExp(format('^{0}', REF_NAME));
141 var rx_directive_tail = new RegExp(format('^::{0}', TAIL));
142 var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1));
143 var rx_substitution_sepa = new RegExp(format('^{0}', SEPA));
144 var rx_substitution_name = new RegExp(format('^{0}', REF_NAME));
145 var rx_substitution_tail = new RegExp(format('^::{0}', TAIL));
146 var rx_link_head = new RegExp("^_");
147 var rx_link_name = new RegExp(format('^{0}|_', REF_NAME));
148 var rx_link_tail = new RegExp(format('^:{0}', TAIL));
149
150 var rx_verbatim = new RegExp('^::\\s*$');
151 var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s');
152
153 ///////////////////////////////////////////////////////////////////////////
154 ///////////////////////////////////////////////////////////////////////////
155
156 function to_normal(stream, state) {
157 var token = null;
158
159 if (stream.sol() && stream.match(rx_examples, false)) {
160 change(state, to_mode, {
161 mode: mode_python, local: CodeMirror.startState(mode_python)
162 });
163 } else if (stream.sol() && stream.match(rx_explicit)) {
164 change(state, to_explicit);
165 token = 'meta';
166 } else if (stream.sol() && stream.match(rx_section)) {
167 change(state, to_normal);
168 token = 'header';
169 } else if (phase(state) == rx_role_pre ||
170 stream.match(rx_role_pre, false)) {
171
172 switch (stage(state)) {
173 case 0:
174 change(state, to_normal, context(rx_role_pre, 1));
175 stream.match(/^:/);
176 token = 'meta';
177 break;
178 case 1:
179 change(state, to_normal, context(rx_role_pre, 2));
180 stream.match(rx_NAME);
181 token = 'keyword';
182
183 if (stream.current().match(/^(?:math|latex)/)) {
184 state.tmp_stex = true;
185 }
186 break;
187 case 2:
188 change(state, to_normal, context(rx_role_pre, 3));
189 stream.match(/^:`/);
190 token = 'meta';
191 break;
192 case 3:
193 if (state.tmp_stex) {
194 state.tmp_stex = undefined; state.tmp = {
195 mode: mode_stex, local: CodeMirror.startState(mode_stex)
196 };
197 }
198
199 if (state.tmp) {
200 if (stream.peek() == '`') {
201 change(state, to_normal, context(rx_role_pre, 4));
202 state.tmp = undefined;
203 break;
204 }
205
206 token = state.tmp.mode.token(stream, state.tmp.local);
207 break;
208 }
209
210 change(state, to_normal, context(rx_role_pre, 4));
211 stream.match(rx_TEXT2);
212 token = 'string';
213 break;
214 case 4:
215 change(state, to_normal, context(rx_role_pre, 5));
216 stream.match(/^`/);
217 token = 'meta';
218 break;
219 case 5:
220 change(state, to_normal, context(rx_role_pre, 6));
221 stream.match(rx_TAIL);
222 break;
223 default:
224 change(state, to_normal);
225 }
226 } else if (phase(state) == rx_role_suf ||
227 stream.match(rx_role_suf, false)) {
228
229 switch (stage(state)) {
230 case 0:
231 change(state, to_normal, context(rx_role_suf, 1));
232 stream.match(/^`/);
233 token = 'meta';
234 break;
235 case 1:
236 change(state, to_normal, context(rx_role_suf, 2));
237 stream.match(rx_TEXT2);
238 token = 'string';
239 break;
240 case 2:
241 change(state, to_normal, context(rx_role_suf, 3));
242 stream.match(/^`:/);
243 token = 'meta';
244 break;
245 case 3:
246 change(state, to_normal, context(rx_role_suf, 4));
247 stream.match(rx_NAME);
248 token = 'keyword';
249 break;
250 case 4:
251 change(state, to_normal, context(rx_role_suf, 5));
252 stream.match(/^:/);
253 token = 'meta';
254 break;
255 case 5:
256 change(state, to_normal, context(rx_role_suf, 6));
257 stream.match(rx_TAIL);
258 break;
259 default:
260 change(state, to_normal);
261 }
262 } else if (phase(state) == rx_role || stream.match(rx_role, false)) {
263
264 switch (stage(state)) {
265 case 0:
266 change(state, to_normal, context(rx_role, 1));
267 stream.match(/^:/);
268 token = 'meta';
269 break;
270 case 1:
271 change(state, to_normal, context(rx_role, 2));
272 stream.match(rx_NAME);
273 token = 'keyword';
274 break;
275 case 2:
276 change(state, to_normal, context(rx_role, 3));
277 stream.match(/^:/);
278 token = 'meta';
279 break;
280 case 3:
281 change(state, to_normal, context(rx_role, 4));
282 stream.match(rx_TAIL);
283 break;
284 default:
285 change(state, to_normal);
286 }
287 } else if (phase(state) == rx_substitution_ref ||
288 stream.match(rx_substitution_ref, false)) {
289
290 switch (stage(state)) {
291 case 0:
292 change(state, to_normal, context(rx_substitution_ref, 1));
293 stream.match(rx_substitution_text);
294 token = 'variable-2';
295 break;
296 case 1:
297 change(state, to_normal, context(rx_substitution_ref, 2));
298 if (stream.match(/^_?_?/)) token = 'link';
299 break;
300 default:
301 change(state, to_normal);
302 }
303 } else if (stream.match(rx_footnote_ref)) {
304 change(state, to_normal);
305 token = 'quote';
306 } else if (stream.match(rx_citation_ref)) {
307 change(state, to_normal);
308 token = 'quote';
309 } else if (stream.match(rx_link_ref1)) {
310 change(state, to_normal);
311 if (!stream.peek() || stream.peek().match(/^\W$/)) {
312 token = 'link';
313 }
314 } else if (phase(state) == rx_link_ref2 ||
315 stream.match(rx_link_ref2, false)) {
316
317 switch (stage(state)) {
318 case 0:
319 if (!stream.peek() || stream.peek().match(/^\W$/)) {
320 change(state, to_normal, context(rx_link_ref2, 1));
321 } else {
322 stream.match(rx_link_ref2);
323 }
324 break;
325 case 1:
326 change(state, to_normal, context(rx_link_ref2, 2));
327 stream.match(/^`/);
328 token = 'link';
329 break;
330 case 2:
331 change(state, to_normal, context(rx_link_ref2, 3));
332 stream.match(rx_TEXT2);
333 break;
334 case 3:
335 change(state, to_normal, context(rx_link_ref2, 4));
336 stream.match(/^`_/);
337 token = 'link';
338 break;
339 default:
340 change(state, to_normal);
341 }
342 } else if (stream.match(rx_verbatim)) {
343 change(state, to_verbatim);
344 }
345
346 else {
347 if (stream.next()) change(state, to_normal);
348 }
349
350 return token;
351 }
352
353 ///////////////////////////////////////////////////////////////////////////
354 ///////////////////////////////////////////////////////////////////////////
355
356 function to_explicit(stream, state) {
357 var token = null;
358
359 if (phase(state) == rx_substitution ||
360 stream.match(rx_substitution, false)) {
361
362 switch (stage(state)) {
363 case 0:
364 change(state, to_explicit, context(rx_substitution, 1));
365 stream.match(rx_substitution_text);
366 token = 'variable-2';
367 break;
368 case 1:
369 change(state, to_explicit, context(rx_substitution, 2));
370 stream.match(rx_substitution_sepa);
371 break;
372 case 2:
373 change(state, to_explicit, context(rx_substitution, 3));
374 stream.match(rx_substitution_name);
375 token = 'keyword';
376 break;
377 case 3:
378 change(state, to_explicit, context(rx_substitution, 4));
379 stream.match(rx_substitution_tail);
380 token = 'meta';
381 break;
382 default:
383 change(state, to_normal);
384 }
385 } else if (phase(state) == rx_directive ||
386 stream.match(rx_directive, false)) {
387
388 switch (stage(state)) {
389 case 0:
390 change(state, to_explicit, context(rx_directive, 1));
391 stream.match(rx_directive_name);
392 token = 'keyword';
393
394 if (stream.current().match(/^(?:math|latex)/))
395 state.tmp_stex = true;
396 else if (stream.current().match(/^python/))
397 state.tmp_py = true;
398 break;
399 case 1:
400 change(state, to_explicit, context(rx_directive, 2));
401 stream.match(rx_directive_tail);
402 token = 'meta';
403
404 if (stream.match(/^latex\s*$/) || state.tmp_stex) {
405 state.tmp_stex = undefined; change(state, to_mode, {
406 mode: mode_stex, local: CodeMirror.startState(mode_stex)
407 });
408 }
409 break;
410 case 2:
411 change(state, to_explicit, context(rx_directive, 3));
412 if (stream.match(/^python\s*$/) || state.tmp_py) {
413 state.tmp_py = undefined; change(state, to_mode, {
414 mode: mode_python, local: CodeMirror.startState(mode_python)
415 });
416 }
417 break;
418 default:
419 change(state, to_normal);
420 }
421 } else if (phase(state) == rx_link || stream.match(rx_link, false)) {
422
423 switch (stage(state)) {
424 case 0:
425 change(state, to_explicit, context(rx_link, 1));
426 stream.match(rx_link_head);
427 stream.match(rx_link_name);
428 token = 'link';
429 break;
430 case 1:
431 change(state, to_explicit, context(rx_link, 2));
432 stream.match(rx_link_tail);
433 token = 'meta';
434 break;
435 default:
436 change(state, to_normal);
437 }
438 } else if (stream.match(rx_footnote)) {
439 change(state, to_normal);
440 token = 'quote';
441 } else if (stream.match(rx_citation)) {
442 change(state, to_normal);
443 token = 'quote';
444 }
445
446 else {
447 stream.eatSpace();
448 if (stream.eol()) {
449 change(state, to_normal);
450 } else {
451 stream.skipToEnd();
452 change(state, to_comment);
453 token = 'comment';
454 }
455 }
456
457 return token;
458 }
459
460 ///////////////////////////////////////////////////////////////////////////
461 ///////////////////////////////////////////////////////////////////////////
462
463 function to_comment(stream, state) {
464 return as_block(stream, state, 'comment');
465 }
466
467 function to_verbatim(stream, state) {
468 return as_block(stream, state, 'meta');
469 }
470
471 function as_block(stream, state, token) {
472 if (stream.eol() || stream.eatSpace()) {
473 stream.skipToEnd();
474 return token;
475 } else {
476 change(state, to_normal);
477 return null;
478 }
479 }
480
481 ///////////////////////////////////////////////////////////////////////////
482 ///////////////////////////////////////////////////////////////////////////
483
484 function to_mode(stream, state) {
485
486 if (state.ctx.mode && state.ctx.local) {
487
488 if (stream.sol()) {
489 if (!stream.eatSpace()) change(state, to_normal);
490 return null;
491 }
492
493 return state.ctx.mode.token(stream, state.ctx.local);
494 }
495
496 change(state, to_normal);
497 return null;
498 }
499
500 ///////////////////////////////////////////////////////////////////////////
501 ///////////////////////////////////////////////////////////////////////////
502
503 function context(phase, stage, mode, local) {
504 return {phase: phase, stage: stage, mode: mode, local: local};
505 }
506
507 function change(state, tok, ctx) {
508 state.tok = tok;
509 state.ctx = ctx || {};
510 }
511
512 function stage(state) {
513 return state.ctx.stage || 0;
514 }
515
516 function phase(state) {
517 return state.ctx.phase;
518 }
519
520 ///////////////////////////////////////////////////////////////////////////
521 ///////////////////////////////////////////////////////////////////////////
522
523 return {
524 startState: function () {
525 return {tok: to_normal, ctx: context(undefined, 0)};
526 },
527
528 copyState: function (state) {
529 var ctx = state.ctx, tmp = state.tmp;
530 if (ctx.local)
531 ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)};
532 if (tmp)
533 tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)};
534 return {tok: state.tok, ctx: ctx, tmp: tmp};
535 },
536
537 innerMode: function (state) {
538 return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode}
539 : state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode}
540 : null;
541 },
542
543 token: function (stream, state) {
544 return state.tok(stream, state);
545 }
546 };
547 }, 'python', 'stex');
548
549 ///////////////////////////////////////////////////////////////////////////////
550 ///////////////////////////////////////////////////////////////////////////////
551
552 CodeMirror.defineMIME('text/x-rst', 'rst');
553
554 ///////////////////////////////////////////////////////////////////////////////
555 ///////////////////////////////////////////////////////////////////////////////
556
557 });
@@ -1,285 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("ruby", function(config) {
15 function wordObj(words) {
16 var o = {};
17 for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
18 return o;
19 }
20 var keywords = wordObj([
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",
23 "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
24 "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
26 "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
27 ]);
28 var indentWords = wordObj(["def", "class", "case", "for", "while", "module", "then",
29 "catch", "loop", "proc", "begin"]);
30 var dedentWords = wordObj(["end", "until"]);
31 var matching = {"[": "]", "{": "}", "(": ")"};
32 var curPunc;
33
34 function chain(newtok, stream, state) {
35 state.tokenize.push(newtok);
36 return newtok(stream, state);
37 }
38
39 function tokenBase(stream, state) {
40 curPunc = null;
41 if (stream.sol() && stream.match("=begin") && stream.eol()) {
42 state.tokenize.push(readBlockComment);
43 return "comment";
44 }
45 if (stream.eatSpace()) return null;
46 var ch = stream.next(), m;
47 if (ch == "`" || ch == "'" || ch == '"') {
48 return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
49 } else if (ch == "/") {
50 var currentIndex = stream.current().length;
51 if (stream.skipTo("/")) {
52 var search_till = stream.current().length;
53 stream.backUp(stream.current().length - currentIndex);
54 var balance = 0; // balance brackets
55 while (stream.current().length < search_till) {
56 var chchr = stream.next();
57 if (chchr == "(") balance += 1;
58 else if (chchr == ")") balance -= 1;
59 if (balance < 0) break;
60 }
61 stream.backUp(stream.current().length - currentIndex);
62 if (balance == 0)
63 return chain(readQuoted(ch, "string-2", true), stream, state);
64 }
65 return "operator";
66 } else if (ch == "%") {
67 var style = "string", embed = true;
68 if (stream.eat("s")) style = "atom";
69 else if (stream.eat(/[WQ]/)) style = "string";
70 else if (stream.eat(/[r]/)) style = "string-2";
71 else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
72 var delim = stream.eat(/[^\w\s=]/);
73 if (!delim) return "operator";
74 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
75 return chain(readQuoted(delim, style, embed, true), stream, state);
76 } else if (ch == "#") {
77 stream.skipToEnd();
78 return "comment";
79 } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
80 return chain(readHereDoc(m[1]), stream, state);
81 } else if (ch == "0") {
82 if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
83 else if (stream.eat("b")) stream.eatWhile(/[01]/);
84 else stream.eatWhile(/[0-7]/);
85 return "number";
86 } else if (/\d/.test(ch)) {
87 stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
88 return "number";
89 } else if (ch == "?") {
90 while (stream.match(/^\\[CM]-/)) {}
91 if (stream.eat("\\")) stream.eatWhile(/\w/);
92 else stream.next();
93 return "string";
94 } else if (ch == ":") {
95 if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
96 if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
97
98 // :> :>> :< :<< are valid symbols
99 if (stream.eat(/[\<\>]/)) {
100 stream.eat(/[\<\>]/);
101 return "atom";
102 }
103
104 // :+ :- :/ :* :| :& :! are valid symbols
105 if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
106 return "atom";
107 }
108
109 // Symbols can't start by a digit
110 if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
111 stream.eatWhile(/[\w$\xa1-\uffff]/);
112 // Only one ? ! = is allowed and only as the last character
113 stream.eat(/[\?\!\=]/);
114 return "atom";
115 }
116 return "operator";
117 } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
118 stream.eat("@");
119 stream.eatWhile(/[\w\xa1-\uffff]/);
120 return "variable-2";
121 } else if (ch == "$") {
122 if (stream.eat(/[a-zA-Z_]/)) {
123 stream.eatWhile(/[\w]/);
124 } else if (stream.eat(/\d/)) {
125 stream.eat(/\d/);
126 } else {
127 stream.next(); // Must be a special global like $: or $!
128 }
129 return "variable-3";
130 } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
131 stream.eatWhile(/[\w\xa1-\uffff]/);
132 stream.eat(/[\?\!]/);
133 if (stream.eat(":")) return "atom";
134 return "ident";
135 } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
136 curPunc = "|";
137 return null;
138 } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
139 curPunc = ch;
140 return null;
141 } else if (ch == "-" && stream.eat(">")) {
142 return "arrow";
143 } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
144 var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
145 if (ch == "." && !more) curPunc = ".";
146 return "operator";
147 } else {
148 return null;
149 }
150 }
151
152 function tokenBaseUntilBrace(depth) {
153 if (!depth) depth = 1;
154 return function(stream, state) {
155 if (stream.peek() == "}") {
156 if (depth == 1) {
157 state.tokenize.pop();
158 return state.tokenize[state.tokenize.length-1](stream, state);
159 } else {
160 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
161 }
162 } else if (stream.peek() == "{") {
163 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
164 }
165 return tokenBase(stream, state);
166 };
167 }
168 function tokenBaseOnce() {
169 var alreadyCalled = false;
170 return function(stream, state) {
171 if (alreadyCalled) {
172 state.tokenize.pop();
173 return state.tokenize[state.tokenize.length-1](stream, state);
174 }
175 alreadyCalled = true;
176 return tokenBase(stream, state);
177 };
178 }
179 function readQuoted(quote, style, embed, unescaped) {
180 return function(stream, state) {
181 var escaped = false, ch;
182
183 if (state.context.type === 'read-quoted-paused') {
184 state.context = state.context.prev;
185 stream.eat("}");
186 }
187
188 while ((ch = stream.next()) != null) {
189 if (ch == quote && (unescaped || !escaped)) {
190 state.tokenize.pop();
191 break;
192 }
193 if (embed && ch == "#" && !escaped) {
194 if (stream.eat("{")) {
195 if (quote == "}") {
196 state.context = {prev: state.context, type: 'read-quoted-paused'};
197 }
198 state.tokenize.push(tokenBaseUntilBrace());
199 break;
200 } else if (/[@\$]/.test(stream.peek())) {
201 state.tokenize.push(tokenBaseOnce());
202 break;
203 }
204 }
205 escaped = !escaped && ch == "\\";
206 }
207 return style;
208 };
209 }
210 function readHereDoc(phrase) {
211 return function(stream, state) {
212 if (stream.match(phrase)) state.tokenize.pop();
213 else stream.skipToEnd();
214 return "string";
215 };
216 }
217 function readBlockComment(stream, state) {
218 if (stream.sol() && stream.match("=end") && stream.eol())
219 state.tokenize.pop();
220 stream.skipToEnd();
221 return "comment";
222 }
223
224 return {
225 startState: function() {
226 return {tokenize: [tokenBase],
227 indented: 0,
228 context: {type: "top", indented: -config.indentUnit},
229 continuedLine: false,
230 lastTok: null,
231 varList: false};
232 },
233
234 token: function(stream, state) {
235 if (stream.sol()) state.indented = stream.indentation();
236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
237 var thisTok = curPunc;
238 if (style == "ident") {
239 var word = stream.current();
240 style = state.lastTok == "." ? "property"
241 : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
242 : /^[A-Z]/.test(word) ? "tag"
243 : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
244 : "variable";
245 if (style == "keyword") {
246 thisTok = word;
247 if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
248 else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
249 else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
250 kwtype = "indent";
251 else if (word == "do" && state.context.indented < state.indented)
252 kwtype = "indent";
253 }
254 }
255 if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
256 if (curPunc == "|") state.varList = !state.varList;
257
258 if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
259 state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
260 else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
261 state.context = state.context.prev;
262
263 if (stream.eol())
264 state.continuedLine = (curPunc == "\\" || style == "operator");
265 return style;
266 },
267
268 indent: function(state, textAfter) {
269 if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
270 var firstChar = textAfter && textAfter.charAt(0);
271 var ct = state.context;
272 var closing = ct.type == matching[firstChar] ||
273 ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
274 return ct.indented + (closing ? 0 : config.indentUnit) +
275 (state.continuedLine ? config.indentUnit : 0);
276 },
277
278 electricChars: "}de", // enD and rescuE
279 lineComment: "#"
280 };
281 });
282
283 CodeMirror.defineMIME("text/x-ruby", "ruby");
284
285 });
@@ -1,451 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("rust", function() {
15 var indentUnit = 4, altIndentUnit = 2;
16 var valKeywords = {
17 "if": "if-style", "while": "if-style", "loop": "else-style", "else": "else-style",
18 "do": "else-style", "ret": "else-style", "fail": "else-style",
19 "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
20 "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
21 "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
22 "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
23 "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
24 "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
25 "use": "op", "bind": "op", "self": "atom", "struct": "enum"
26 };
27 var typeKeywords = function() {
28 var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
29 var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
30 for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
31 return keywords;
32 }();
33 var operatorChar = /[+\-*&%=<>!?|\.@]/;
34
35 // Tokenizer
36
37 // Used as scratch variable to communicate multiple values without
38 // consing up tons of objects.
39 var tcat, content;
40 function r(tc, style) {
41 tcat = tc;
42 return style;
43 }
44
45 function tokenBase(stream, state) {
46 var ch = stream.next();
47 if (ch == '"') {
48 state.tokenize = tokenString;
49 return state.tokenize(stream, state);
50 }
51 if (ch == "'") {
52 tcat = "atom";
53 if (stream.eat("\\")) {
54 if (stream.skipTo("'")) { stream.next(); return "string"; }
55 else { return "error"; }
56 } else {
57 stream.next();
58 return stream.eat("'") ? "string" : "error";
59 }
60 }
61 if (ch == "/") {
62 if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
63 if (stream.eat("*")) {
64 state.tokenize = tokenComment(1);
65 return state.tokenize(stream, state);
66 }
67 }
68 if (ch == "#") {
69 if (stream.eat("[")) { tcat = "open-attr"; return null; }
70 stream.eatWhile(/\w/);
71 return r("macro", "meta");
72 }
73 if (ch == ":" && stream.match(":<")) {
74 return r("op", null);
75 }
76 if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
77 var flp = false;
78 if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
79 stream.eatWhile(/\d/);
80 if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
81 if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
82 }
83 if (flp) stream.match(/^f(?:32|64)/);
84 else stream.match(/^[ui](?:8|16|32|64)/);
85 return r("atom", "number");
86 }
87 if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
88 if (ch == "-" && stream.eat(">")) return r("->", null);
89 if (ch.match(operatorChar)) {
90 stream.eatWhile(operatorChar);
91 return r("op", null);
92 }
93 stream.eatWhile(/\w/);
94 content = stream.current();
95 if (stream.match(/^::\w/)) {
96 stream.backUp(1);
97 return r("prefix", "variable-2");
98 }
99 if (state.keywords.propertyIsEnumerable(content))
100 return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
101 return r("name", "variable");
102 }
103
104 function tokenString(stream, state) {
105 var ch, escaped = false;
106 while (ch = stream.next()) {
107 if (ch == '"' && !escaped) {
108 state.tokenize = tokenBase;
109 return r("atom", "string");
110 }
111 escaped = !escaped && ch == "\\";
112 }
113 // Hack to not confuse the parser when a string is split in
114 // pieces.
115 return r("op", "string");
116 }
117
118 function tokenComment(depth) {
119 return function(stream, state) {
120 var lastCh = null, ch;
121 while (ch = stream.next()) {
122 if (ch == "/" && lastCh == "*") {
123 if (depth == 1) {
124 state.tokenize = tokenBase;
125 break;
126 } else {
127 state.tokenize = tokenComment(depth - 1);
128 return state.tokenize(stream, state);
129 }
130 }
131 if (ch == "*" && lastCh == "/") {
132 state.tokenize = tokenComment(depth + 1);
133 return state.tokenize(stream, state);
134 }
135 lastCh = ch;
136 }
137 return "comment";
138 };
139 }
140
141 // Parser
142
143 var cx = {state: null, stream: null, marked: null, cc: null};
144 function pass() {
145 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
146 }
147 function cont() {
148 pass.apply(null, arguments);
149 return true;
150 }
151
152 function pushlex(type, info) {
153 var result = function() {
154 var state = cx.state;
155 state.lexical = {indented: state.indented, column: cx.stream.column(),
156 type: type, prev: state.lexical, info: info};
157 };
158 result.lex = true;
159 return result;
160 }
161 function poplex() {
162 var state = cx.state;
163 if (state.lexical.prev) {
164 if (state.lexical.type == ")")
165 state.indented = state.lexical.indented;
166 state.lexical = state.lexical.prev;
167 }
168 }
169 function typecx() { cx.state.keywords = typeKeywords; }
170 function valcx() { cx.state.keywords = valKeywords; }
171 poplex.lex = typecx.lex = valcx.lex = true;
172
173 function commasep(comb, end) {
174 function more(type) {
175 if (type == ",") return cont(comb, more);
176 if (type == end) return cont();
177 return cont(more);
178 }
179 return function(type) {
180 if (type == end) return cont();
181 return pass(comb, more);
182 };
183 }
184
185 function stat_of(comb, tag) {
186 return cont(pushlex("stat", tag), comb, poplex, block);
187 }
188 function block(type) {
189 if (type == "}") return cont();
190 if (type == "let") return stat_of(letdef1, "let");
191 if (type == "fn") return stat_of(fndef);
192 if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
193 if (type == "enum") return stat_of(enumdef);
194 if (type == "mod") return stat_of(mod);
195 if (type == "iface") return stat_of(iface);
196 if (type == "impl") return stat_of(impl);
197 if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
198 if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
199 return pass(pushlex("stat"), expression, poplex, endstatement, block);
200 }
201 function endstatement(type) {
202 if (type == ";") return cont();
203 return pass();
204 }
205 function expression(type) {
206 if (type == "atom" || type == "name") return cont(maybeop);
207 if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
208 if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
209 if (type.match(/[\]\)\};,]/)) return pass();
210 if (type == "if-style") return cont(expression, expression);
211 if (type == "else-style" || type == "op") return cont(expression);
212 if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
213 if (type == "alt") return cont(expression, altbody);
214 if (type == "fn") return cont(fndef);
215 if (type == "macro") return cont(macro);
216 return cont();
217 }
218 function maybeop(type) {
219 if (content == ".") return cont(maybeprop);
220 if (content == "::<"){return cont(typarams, maybeop);}
221 if (type == "op" || content == ":") return cont(expression);
222 if (type == "(" || type == "[") return matchBrackets(type, expression);
223 return pass();
224 }
225 function maybeprop() {
226 if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
227 return pass(expression);
228 }
229 function exprbrace(type) {
230 if (type == "op") {
231 if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
232 if (content == "||") return cont(poplex, pushlex("}", "block"), block);
233 }
234 if (content == "mutable" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
235 && !cx.stream.match("::", false)))
236 return pass(record_of(expression));
237 return pass(block);
238 }
239 function record_of(comb) {
240 function ro(type) {
241 if (content == "mutable" || content == "with") {cx.marked = "keyword"; return cont(ro);}
242 if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
243 if (type == ":") return cont(comb, ro);
244 if (type == "}") return cont();
245 return cont(ro);
246 }
247 return ro;
248 }
249 function blockvars(type) {
250 if (type == "name") {cx.marked = "def"; return cont(blockvars);}
251 if (type == "op" && content == "|") return cont();
252 return cont(blockvars);
253 }
254
255 function letdef1(type) {
256 if (type.match(/[\]\)\};]/)) return cont();
257 if (content == "=") return cont(expression, letdef2);
258 if (type == ",") return cont(letdef1);
259 return pass(pattern, maybetype, letdef1);
260 }
261 function letdef2(type) {
262 if (type.match(/[\]\)\};,]/)) return pass(letdef1);
263 else return pass(expression, letdef2);
264 }
265 function maybetype(type) {
266 if (type == ":") return cont(typecx, rtype, valcx);
267 return pass();
268 }
269 function inop(type) {
270 if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
271 return pass();
272 }
273 function fndef(type) {
274 if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
275 if (type == "name") {cx.marked = "def"; return cont(fndef);}
276 if (content == "<") return cont(typarams, fndef);
277 if (type == "{") return pass(expression);
278 if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
279 if (type == "->") return cont(typecx, rtype, valcx, fndef);
280 if (type == ";") return cont();
281 return cont(fndef);
282 }
283 function tydef(type) {
284 if (type == "name") {cx.marked = "def"; return cont(tydef);}
285 if (content == "<") return cont(typarams, tydef);
286 if (content == "=") return cont(typecx, rtype, valcx);
287 return cont(tydef);
288 }
289 function enumdef(type) {
290 if (type == "name") {cx.marked = "def"; return cont(enumdef);}
291 if (content == "<") return cont(typarams, enumdef);
292 if (content == "=") return cont(typecx, rtype, valcx, endstatement);
293 if (type == "{") return cont(pushlex("}"), typecx, enumblock, valcx, poplex);
294 return cont(enumdef);
295 }
296 function enumblock(type) {
297 if (type == "}") return cont();
298 if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, enumblock);
299 if (content.match(/^\w+$/)) cx.marked = "def";
300 return cont(enumblock);
301 }
302 function mod(type) {
303 if (type == "name") {cx.marked = "def"; return cont(mod);}
304 if (type == "{") return cont(pushlex("}"), block, poplex);
305 return pass();
306 }
307 function iface(type) {
308 if (type == "name") {cx.marked = "def"; return cont(iface);}
309 if (content == "<") return cont(typarams, iface);
310 if (type == "{") return cont(pushlex("}"), block, poplex);
311 return pass();
312 }
313 function impl(type) {
314 if (content == "<") return cont(typarams, impl);
315 if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
316 if (type == "name") {cx.marked = "def"; return cont(impl);}
317 if (type == "{") return cont(pushlex("}"), block, poplex);
318 return pass();
319 }
320 function typarams() {
321 if (content == ">") return cont();
322 if (content == ",") return cont(typarams);
323 if (content == ":") return cont(rtype, typarams);
324 return pass(rtype, typarams);
325 }
326 function argdef(type) {
327 if (type == "name") {cx.marked = "def"; return cont(argdef);}
328 if (type == ":") return cont(typecx, rtype, valcx);
329 return pass();
330 }
331 function rtype(type) {
332 if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
333 if (content == "mutable") {cx.marked = "keyword"; return cont(rtype);}
334 if (type == "atom") return cont(rtypemaybeparam);
335 if (type == "op" || type == "obj") return cont(rtype);
336 if (type == "fn") return cont(fntype);
337 if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
338 return matchBrackets(type, rtype);
339 }
340 function rtypemaybeparam() {
341 if (content == "<") return cont(typarams);
342 return pass();
343 }
344 function fntype(type) {
345 if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
346 if (type == "->") return cont(rtype);
347 return pass();
348 }
349 function pattern(type) {
350 if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
351 if (type == "atom") return cont(patternmaybeop);
352 if (type == "op") return cont(pattern);
353 if (type.match(/[\]\)\};,]/)) return pass();
354 return matchBrackets(type, pattern);
355 }
356 function patternmaybeop(type) {
357 if (type == "op" && content == ".") return cont();
358 if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
359 else return pass();
360 }
361 function altbody(type) {
362 if (type == "{") return cont(pushlex("}", "alt"), altblock1, poplex);
363 return pass();
364 }
365 function altblock1(type) {
366 if (type == "}") return cont();
367 if (type == "|") return cont(altblock1);
368 if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
369 if (type.match(/[\]\);,]/)) return cont(altblock1);
370 return pass(pattern, altblock2);
371 }
372 function altblock2(type) {
373 if (type == "{") return cont(pushlex("}", "alt"), block, poplex, altblock1);
374 else return pass(altblock1);
375 }
376
377 function macro(type) {
378 if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
379 return pass();
380 }
381 function matchBrackets(type, comb) {
382 if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
383 if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
384 if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
385 return cont();
386 }
387
388 function parse(state, stream, style) {
389 var cc = state.cc;
390 // Communicate our context to the combinators.
391 // (Less wasteful than consing up a hundred closures on every call.)
392 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
393
394 while (true) {
395 var combinator = cc.length ? cc.pop() : block;
396 if (combinator(tcat)) {
397 while(cc.length && cc[cc.length - 1].lex)
398 cc.pop()();
399 return cx.marked || style;
400 }
401 }
402 }
403
404 return {
405 startState: function() {
406 return {
407 tokenize: tokenBase,
408 cc: [],
409 lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
410 keywords: valKeywords,
411 indented: 0
412 };
413 },
414
415 token: function(stream, state) {
416 if (stream.sol()) {
417 if (!state.lexical.hasOwnProperty("align"))
418 state.lexical.align = false;
419 state.indented = stream.indentation();
420 }
421 if (stream.eatSpace()) return null;
422 tcat = content = null;
423 var style = state.tokenize(stream, state);
424 if (style == "comment") return style;
425 if (!state.lexical.hasOwnProperty("align"))
426 state.lexical.align = true;
427 if (tcat == "prefix") return style;
428 if (!content) content = stream.current();
429 return parse(state, stream, style);
430 },
431
432 indent: function(state, textAfter) {
433 if (state.tokenize != tokenBase) return 0;
434 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
435 type = lexical.type, closing = firstChar == type;
436 if (type == "stat") return lexical.indented + indentUnit;
437 if (lexical.align) return lexical.column + (closing ? 0 : 1);
438 return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
439 },
440
441 electricChars: "{}",
442 blockCommentStart: "/*",
443 blockCommentEnd: "*/",
444 lineComment: "//",
445 fold: "brace"
446 };
447 });
448
449 CodeMirror.defineMIME("text/x-rustsrc", "rust");
450
451 });
@@ -1,327 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("sass", function(config) {
15 function tokenRegexp(words) {
16 return new RegExp("^" + words.join("|"));
17 }
18
19 var keywords = ["true", "false", "null", "auto"];
20 var keywordsRegexp = new RegExp("^" + keywords.join("|"));
21
22 var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
23 var opRegexp = tokenRegexp(operators);
24
25 var pseudoElementsRegexp = /^::?[\w\-]+/;
26
27 function urlTokens(stream, state) {
28 var ch = stream.peek();
29
30 if (ch === ")") {
31 stream.next();
32 state.tokenizer = tokenBase;
33 return "operator";
34 } else if (ch === "(") {
35 stream.next();
36 stream.eatSpace();
37
38 return "operator";
39 } else if (ch === "'" || ch === '"') {
40 state.tokenizer = buildStringTokenizer(stream.next());
41 return "string";
42 } else {
43 state.tokenizer = buildStringTokenizer(")", false);
44 return "string";
45 }
46 }
47 function comment(indentation, multiLine) {
48 return function(stream, state) {
49 if (stream.sol() && stream.indentation() <= indentation) {
50 state.tokenizer = tokenBase;
51 return tokenBase(stream, state);
52 }
53
54 if (multiLine && stream.skipTo("*/")) {
55 stream.next();
56 stream.next();
57 state.tokenizer = tokenBase;
58 } else {
59 stream.next();
60 }
61
62 return "comment";
63 };
64 }
65
66 function buildStringTokenizer(quote, greedy) {
67 if(greedy == null) { greedy = true; }
68
69 function stringTokenizer(stream, state) {
70 var nextChar = stream.next();
71 var peekChar = stream.peek();
72 var previousChar = stream.string.charAt(stream.pos-2);
73
74 var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\"));
75
76 if (endingString) {
77 if (nextChar !== quote && greedy) { stream.next(); }
78 state.tokenizer = tokenBase;
79 return "string";
80 } else if (nextChar === "#" && peekChar === "{") {
81 state.tokenizer = buildInterpolationTokenizer(stringTokenizer);
82 stream.next();
83 return "operator";
84 } else {
85 return "string";
86 }
87 }
88
89 return stringTokenizer;
90 }
91
92 function buildInterpolationTokenizer(currentTokenizer) {
93 return function(stream, state) {
94 if (stream.peek() === "}") {
95 stream.next();
96 state.tokenizer = currentTokenizer;
97 return "operator";
98 } else {
99 return tokenBase(stream, state);
100 }
101 };
102 }
103
104 function indent(state) {
105 if (state.indentCount == 0) {
106 state.indentCount++;
107 var lastScopeOffset = state.scopes[0].offset;
108 var currentOffset = lastScopeOffset + config.indentUnit;
109 state.scopes.unshift({ offset:currentOffset });
110 }
111 }
112
113 function dedent(state) {
114 if (state.scopes.length == 1) return;
115
116 state.scopes.shift();
117 }
118
119 function tokenBase(stream, state) {
120 var ch = stream.peek();
121
122 // Comment
123 if (stream.match("/*")) {
124 state.tokenizer = comment(stream.indentation(), true);
125 return state.tokenizer(stream, state);
126 }
127 if (stream.match("//")) {
128 state.tokenizer = comment(stream.indentation(), false);
129 return state.tokenizer(stream, state);
130 }
131
132 // Interpolation
133 if (stream.match("#{")) {
134 state.tokenizer = buildInterpolationTokenizer(tokenBase);
135 return "operator";
136 }
137
138 if (ch === ".") {
139 stream.next();
140
141 // Match class selectors
142 if (stream.match(/^[\w-]+/)) {
143 indent(state);
144 return "atom";
145 } else if (stream.peek() === "#") {
146 indent(state);
147 return "atom";
148 } else {
149 return "operator";
150 }
151 }
152
153 if (ch === "#") {
154 stream.next();
155
156 // Hex numbers
157 if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/))
158 return "number";
159
160 // ID selectors
161 if (stream.match(/^[\w-]+/)) {
162 indent(state);
163 return "atom";
164 }
165
166 if (stream.peek() === "#") {
167 indent(state);
168 return "atom";
169 }
170 }
171
172 // Numbers
173 if (stream.match(/^-?[0-9\.]+/))
174 return "number";
175
176 // Units
177 if (stream.match(/^(px|em|in)\b/))
178 return "unit";
179
180 if (stream.match(keywordsRegexp))
181 return "keyword";
182
183 if (stream.match(/^url/) && stream.peek() === "(") {
184 state.tokenizer = urlTokens;
185 return "atom";
186 }
187
188 // Variables
189 if (ch === "$") {
190 stream.next();
191 stream.eatWhile(/[\w-]/);
192
193 if (stream.peek() === ":") {
194 stream.next();
195 return "variable-2";
196 } else {
197 return "variable-3";
198 }
199 }
200
201 if (ch === "!") {
202 stream.next();
203 return stream.match(/^[\w]+/) ? "keyword": "operator";
204 }
205
206 if (ch === "=") {
207 stream.next();
208
209 // Match shortcut mixin definition
210 if (stream.match(/^[\w-]+/)) {
211 indent(state);
212 return "meta";
213 } else {
214 return "operator";
215 }
216 }
217
218 if (ch === "+") {
219 stream.next();
220
221 // Match shortcut mixin definition
222 if (stream.match(/^[\w-]+/))
223 return "variable-3";
224 else
225 return "operator";
226 }
227
228 // Indent Directives
229 if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
230 indent(state);
231 return "meta";
232 }
233
234 // Other Directives
235 if (ch === "@") {
236 stream.next();
237 stream.eatWhile(/[\w-]/);
238 return "meta";
239 }
240
241 // Strings
242 if (ch === '"' || ch === "'") {
243 stream.next();
244 state.tokenizer = buildStringTokenizer(ch);
245 return "string";
246 }
247
248 // Pseudo element selectors
249 if (ch == ":" && stream.match(pseudoElementsRegexp))
250 return "keyword";
251
252 // atoms
253 if (stream.eatWhile(/[\w-&]/)) {
254 // matches a property definition
255 if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
256 return "property";
257 else
258 return "atom";
259 }
260
261 if (stream.match(opRegexp))
262 return "operator";
263
264 // If we haven't returned by now, we move 1 character
265 // and return an error
266 stream.next();
267 return null;
268 }
269
270 function tokenLexer(stream, state) {
271 if (stream.sol()) state.indentCount = 0;
272 var style = state.tokenizer(stream, state);
273 var current = stream.current();
274
275 if (current === "@return")
276 dedent(state);
277
278 if (style === "atom")
279 indent(state);
280
281 if (style !== null) {
282 var startOfToken = stream.pos - current.length;
283 var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
284
285 var newScopes = [];
286
287 for (var i = 0; i < state.scopes.length; i++) {
288 var scope = state.scopes[i];
289
290 if (scope.offset <= withCurrentIndent)
291 newScopes.push(scope);
292 }
293
294 state.scopes = newScopes;
295 }
296
297
298 return style;
299 }
300
301 return {
302 startState: function() {
303 return {
304 tokenizer: tokenBase,
305 scopes: [{offset: 0, type: "sass"}],
306 indentCount: 0,
307 definedVars: [],
308 definedMixins: []
309 };
310 },
311 token: function(stream, state) {
312 var style = tokenLexer(stream, state);
313
314 state.lastToken = { style: style, content: stream.current() };
315
316 return style;
317 },
318
319 indent: function(state) {
320 return state.scopes[0].offset;
321 }
322 };
323 });
324
325 CodeMirror.defineMIME("text/x-sass", "sass");
326
327 });
@@ -1,248 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Author: Koh Zi Han, based on implementation by Koh Zi Chun
6 */
7
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15 })(function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("scheme", function () {
19 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
20 ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
21 var INDENT_WORD_SKIP = 2;
22
23 function makeKeywords(str) {
24 var obj = {}, words = str.split(" ");
25 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
26 return obj;
27 }
28
29 var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
30 var indentKeys = makeKeywords("define let letrec let* lambda");
31
32 function stateStack(indent, type, prev) { // represents a state stack object
33 this.indent = indent;
34 this.type = type;
35 this.prev = prev;
36 }
37
38 function pushStack(state, indent, type) {
39 state.indentStack = new stateStack(indent, type, state.indentStack);
40 }
41
42 function popStack(state) {
43 state.indentStack = state.indentStack.prev;
44 }
45
46 var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i);
47 var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i);
48 var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i);
49 var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i);
50
51 function isBinaryNumber (stream) {
52 return stream.match(binaryMatcher);
53 }
54
55 function isOctalNumber (stream) {
56 return stream.match(octalMatcher);
57 }
58
59 function isDecimalNumber (stream, backup) {
60 if (backup === true) {
61 stream.backUp(1);
62 }
63 return stream.match(decimalMatcher);
64 }
65
66 function isHexNumber (stream) {
67 return stream.match(hexMatcher);
68 }
69
70 return {
71 startState: function () {
72 return {
73 indentStack: null,
74 indentation: 0,
75 mode: false,
76 sExprComment: false
77 };
78 },
79
80 token: function (stream, state) {
81 if (state.indentStack == null && stream.sol()) {
82 // update indentation, but only if indentStack is empty
83 state.indentation = stream.indentation();
84 }
85
86 // skip spaces
87 if (stream.eatSpace()) {
88 return null;
89 }
90 var returnType = null;
91
92 switch(state.mode){
93 case "string": // multi-line string parsing mode
94 var next, escaped = false;
95 while ((next = stream.next()) != null) {
96 if (next == "\"" && !escaped) {
97
98 state.mode = false;
99 break;
100 }
101 escaped = !escaped && next == "\\";
102 }
103 returnType = STRING; // continue on in scheme-string mode
104 break;
105 case "comment": // comment parsing mode
106 var next, maybeEnd = false;
107 while ((next = stream.next()) != null) {
108 if (next == "#" && maybeEnd) {
109
110 state.mode = false;
111 break;
112 }
113 maybeEnd = (next == "|");
114 }
115 returnType = COMMENT;
116 break;
117 case "s-expr-comment": // s-expr commenting mode
118 state.mode = false;
119 if(stream.peek() == "(" || stream.peek() == "["){
120 // actually start scheme s-expr commenting mode
121 state.sExprComment = 0;
122 }else{
123 // if not we just comment the entire of the next token
124 stream.eatWhile(/[^/s]/); // eat non spaces
125 returnType = COMMENT;
126 break;
127 }
128 default: // default parsing mode
129 var ch = stream.next();
130
131 if (ch == "\"") {
132 state.mode = "string";
133 returnType = STRING;
134
135 } else if (ch == "'") {
136 returnType = ATOM;
137 } else if (ch == '#') {
138 if (stream.eat("|")) { // Multi-line comment
139 state.mode = "comment"; // toggle to comment mode
140 returnType = COMMENT;
141 } else if (stream.eat(/[tf]/i)) { // #t/#f (atom)
142 returnType = ATOM;
143 } else if (stream.eat(';')) { // S-Expr comment
144 state.mode = "s-expr-comment";
145 returnType = COMMENT;
146 } else {
147 var numTest = null, hasExactness = false, hasRadix = true;
148 if (stream.eat(/[ei]/i)) {
149 hasExactness = true;
150 } else {
151 stream.backUp(1); // must be radix specifier
152 }
153 if (stream.match(/^#b/i)) {
154 numTest = isBinaryNumber;
155 } else if (stream.match(/^#o/i)) {
156 numTest = isOctalNumber;
157 } else if (stream.match(/^#x/i)) {
158 numTest = isHexNumber;
159 } else if (stream.match(/^#d/i)) {
160 numTest = isDecimalNumber;
161 } else if (stream.match(/^[-+0-9.]/, false)) {
162 hasRadix = false;
163 numTest = isDecimalNumber;
164 // re-consume the intial # if all matches failed
165 } else if (!hasExactness) {
166 stream.eat('#');
167 }
168 if (numTest != null) {
169 if (hasRadix && !hasExactness) {
170 // consume optional exactness after radix
171 stream.match(/^#[ei]/i);
172 }
173 if (numTest(stream))
174 returnType = NUMBER;
175 }
176 }
177 } else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal
178 returnType = NUMBER;
179 } else if (ch == ";") { // comment
180 stream.skipToEnd(); // rest of the line is a comment
181 returnType = COMMENT;
182 } else if (ch == "(" || ch == "[") {
183 var keyWord = ''; var indentTemp = stream.column(), letter;
184 /**
185 Either
186 (indent-word ..
187 (non-indent-word ..
188 (;something else, bracket, etc.
189 */
190
191 while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) {
192 keyWord += letter;
193 }
194
195 if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word
196
197 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
198 } else { // non-indent word
199 // we continue eating the spaces
200 stream.eatSpace();
201 if (stream.eol() || stream.peek() == ";") {
202 // nothing significant after
203 // we restart indentation 1 space after
204 pushStack(state, indentTemp + 1, ch);
205 } else {
206 pushStack(state, indentTemp + stream.current().length, ch); // else we match
207 }
208 }
209 stream.backUp(stream.current().length - 1); // undo all the eating
210
211 if(typeof state.sExprComment == "number") state.sExprComment++;
212
213 returnType = BRACKET;
214 } else if (ch == ")" || ch == "]") {
215 returnType = BRACKET;
216 if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) {
217 popStack(state);
218
219 if(typeof state.sExprComment == "number"){
220 if(--state.sExprComment == 0){
221 returnType = COMMENT; // final closing bracket
222 state.sExprComment = false; // turn off s-expr commenting mode
223 }
224 }
225 }
226 } else {
227 stream.eatWhile(/[\w\$_\-!$%&*+\.\/:<=>?@\^~]/);
228
229 if (keywords && keywords.propertyIsEnumerable(stream.current())) {
230 returnType = BUILTIN;
231 } else returnType = "variable";
232 }
233 }
234 return (typeof state.sExprComment == "number") ? COMMENT : returnType;
235 },
236
237 indent: function (state) {
238 if (state.indentStack == null) return state.indentation;
239 return state.indentStack.indent;
240 },
241
242 lineComment: ";;"
243 };
244 });
245
246 CodeMirror.defineMIME("text/x-scheme", "scheme");
247
248 });
@@ -1,138 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('shell', function() {
15
16 var words = {};
17 function define(style, string) {
18 var split = string.split(' ');
19 for(var i = 0; i < split.length; i++) {
20 words[split[i]] = style;
21 }
22 };
23
24 // Atoms
25 define('atom', 'true false');
26
27 // Keywords
28 define('keyword', 'if then do else elif while until for in esac fi fin ' +
29 'fil done exit set unset export function');
30
31 // Commands
32 define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
33 'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
34 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
35 'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
36 'touch vi vim wall wc wget who write yes zsh');
37
38 function tokenBase(stream, state) {
39 if (stream.eatSpace()) return null;
40
41 var sol = stream.sol();
42 var ch = stream.next();
43
44 if (ch === '\\') {
45 stream.next();
46 return null;
47 }
48 if (ch === '\'' || ch === '"' || ch === '`') {
49 state.tokens.unshift(tokenString(ch));
50 return tokenize(stream, state);
51 }
52 if (ch === '#') {
53 if (sol && stream.eat('!')) {
54 stream.skipToEnd();
55 return 'meta'; // 'comment'?
56 }
57 stream.skipToEnd();
58 return 'comment';
59 }
60 if (ch === '$') {
61 state.tokens.unshift(tokenDollar);
62 return tokenize(stream, state);
63 }
64 if (ch === '+' || ch === '=') {
65 return 'operator';
66 }
67 if (ch === '-') {
68 stream.eat('-');
69 stream.eatWhile(/\w/);
70 return 'attribute';
71 }
72 if (/\d/.test(ch)) {
73 stream.eatWhile(/\d/);
74 if(stream.eol() || !/\w/.test(stream.peek())) {
75 return 'number';
76 }
77 }
78 stream.eatWhile(/[\w-]/);
79 var cur = stream.current();
80 if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
81 return words.hasOwnProperty(cur) ? words[cur] : null;
82 }
83
84 function tokenString(quote) {
85 return function(stream, state) {
86 var next, end = false, escaped = false;
87 while ((next = stream.next()) != null) {
88 if (next === quote && !escaped) {
89 end = true;
90 break;
91 }
92 if (next === '$' && !escaped && quote !== '\'') {
93 escaped = true;
94 stream.backUp(1);
95 state.tokens.unshift(tokenDollar);
96 break;
97 }
98 escaped = !escaped && next === '\\';
99 }
100 if (end || !escaped) {
101 state.tokens.shift();
102 }
103 return (quote === '`' || quote === ')' ? 'quote' : 'string');
104 };
105 };
106
107 var tokenDollar = function(stream, state) {
108 if (state.tokens.length > 1) stream.eat('$');
109 var ch = stream.next(), hungry = /\w/;
110 if (ch === '{') hungry = /[^}]/;
111 if (ch === '(') {
112 state.tokens[0] = tokenString(')');
113 return tokenize(stream, state);
114 }
115 if (!/\d/.test(ch)) {
116 stream.eatWhile(hungry);
117 stream.eat('}');
118 }
119 state.tokens.shift();
120 return 'def';
121 };
122
123 function tokenize(stream, state) {
124 return (state.tokens[0] || tokenBase) (stream, state);
125 };
126
127 return {
128 startState: function() {return {tokens:[]};},
129 token: function(stream, state) {
130 return tokenize(stream, state);
131 },
132 lineComment: '#'
133 };
134 });
135
136 CodeMirror.defineMIME('text/x-sh', 'shell');
137
138 });
@@ -1,193 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("sieve", function(config) {
15 function words(str) {
16 var obj = {}, words = str.split(" ");
17 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 return obj;
19 }
20
21 var keywords = words("if elsif else stop require");
22 var atoms = words("true false not");
23 var indentUnit = config.indentUnit;
24
25 function tokenBase(stream, state) {
26
27 var ch = stream.next();
28 if (ch == "/" && stream.eat("*")) {
29 state.tokenize = tokenCComment;
30 return tokenCComment(stream, state);
31 }
32
33 if (ch === '#') {
34 stream.skipToEnd();
35 return "comment";
36 }
37
38 if (ch == "\"") {
39 state.tokenize = tokenString(ch);
40 return state.tokenize(stream, state);
41 }
42
43 if (ch == "(") {
44 state._indent.push("(");
45 // add virtual angel wings so that editor behaves...
46 // ...more sane incase of broken brackets
47 state._indent.push("{");
48 return null;
49 }
50
51 if (ch === "{") {
52 state._indent.push("{");
53 return null;
54 }
55
56 if (ch == ")") {
57 state._indent.pop();
58 state._indent.pop();
59 }
60
61 if (ch === "}") {
62 state._indent.pop();
63 return null;
64 }
65
66 if (ch == ",")
67 return null;
68
69 if (ch == ";")
70 return null;
71
72
73 if (/[{}\(\),;]/.test(ch))
74 return null;
75
76 // 1*DIGIT "K" / "M" / "G"
77 if (/\d/.test(ch)) {
78 stream.eatWhile(/[\d]/);
79 stream.eat(/[KkMmGg]/);
80 return "number";
81 }
82
83 // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_")
84 if (ch == ":") {
85 stream.eatWhile(/[a-zA-Z_]/);
86 stream.eatWhile(/[a-zA-Z0-9_]/);
87
88 return "operator";
89 }
90
91 stream.eatWhile(/\w/);
92 var cur = stream.current();
93
94 // "text:" *(SP / HTAB) (hash-comment / CRLF)
95 // *(multiline-literal / multiline-dotstart)
96 // "." CRLF
97 if ((cur == "text") && stream.eat(":"))
98 {
99 state.tokenize = tokenMultiLineString;
100 return "string";
101 }
102
103 if (keywords.propertyIsEnumerable(cur))
104 return "keyword";
105
106 if (atoms.propertyIsEnumerable(cur))
107 return "atom";
108
109 return null;
110 }
111
112 function tokenMultiLineString(stream, state)
113 {
114 state._multiLineString = true;
115 // the first line is special it may contain a comment
116 if (!stream.sol()) {
117 stream.eatSpace();
118
119 if (stream.peek() == "#") {
120 stream.skipToEnd();
121 return "comment";
122 }
123
124 stream.skipToEnd();
125 return "string";
126 }
127
128 if ((stream.next() == ".") && (stream.eol()))
129 {
130 state._multiLineString = false;
131 state.tokenize = tokenBase;
132 }
133
134 return "string";
135 }
136
137 function tokenCComment(stream, state) {
138 var maybeEnd = false, ch;
139 while ((ch = stream.next()) != null) {
140 if (maybeEnd && ch == "/") {
141 state.tokenize = tokenBase;
142 break;
143 }
144 maybeEnd = (ch == "*");
145 }
146 return "comment";
147 }
148
149 function tokenString(quote) {
150 return function(stream, state) {
151 var escaped = false, ch;
152 while ((ch = stream.next()) != null) {
153 if (ch == quote && !escaped)
154 break;
155 escaped = !escaped && ch == "\\";
156 }
157 if (!escaped) state.tokenize = tokenBase;
158 return "string";
159 };
160 }
161
162 return {
163 startState: function(base) {
164 return {tokenize: tokenBase,
165 baseIndent: base || 0,
166 _indent: []};
167 },
168
169 token: function(stream, state) {
170 if (stream.eatSpace())
171 return null;
172
173 return (state.tokenize || tokenBase)(stream, state);;
174 },
175
176 indent: function(state, _textAfter) {
177 var length = state._indent.length;
178 if (_textAfter && (_textAfter[0] == "}"))
179 length--;
180
181 if (length <0)
182 length = 0;
183
184 return length * indentUnit;
185 },
186
187 electricChars: "}"
188 };
189 });
190
191 CodeMirror.defineMIME("application/sieve", "sieve");
192
193 });
This diff has been collapsed as it changes many lines, (575 lines changed) Show them Hide them
@@ -1,575 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 // Slim Highlighting for CodeMirror copyright (c) HicknHack Software Gmbh
5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMode("slim", function(config) {
17 var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
18 var rubyMode = CodeMirror.getMode(config, "ruby");
19 var modes = { html: htmlMode, ruby: rubyMode };
20 var embedded = {
21 ruby: "ruby",
22 javascript: "javascript",
23 css: "text/css",
24 sass: "text/x-sass",
25 scss: "text/x-scss",
26 less: "text/x-less",
27 styl: "text/x-styl", // no highlighting so far
28 coffee: "coffeescript",
29 asciidoc: "text/x-asciidoc",
30 markdown: "text/x-markdown",
31 textile: "text/x-textile", // no highlighting so far
32 creole: "text/x-creole", // no highlighting so far
33 wiki: "text/x-wiki", // no highlighting so far
34 mediawiki: "text/x-mediawiki", // no highlighting so far
35 rdoc: "text/x-rdoc", // no highlighting so far
36 builder: "text/x-builder", // no highlighting so far
37 nokogiri: "text/x-nokogiri", // no highlighting so far
38 erb: "application/x-erb"
39 };
40 var embeddedRegexp = function(map){
41 var arr = [];
42 for(var key in map) arr.push(key);
43 return new RegExp("^("+arr.join('|')+"):");
44 }(embedded);
45
46 var styleMap = {
47 "commentLine": "comment",
48 "slimSwitch": "operator special",
49 "slimTag": "tag",
50 "slimId": "attribute def",
51 "slimClass": "attribute qualifier",
52 "slimAttribute": "attribute",
53 "slimSubmode": "keyword special",
54 "closeAttributeTag": null,
55 "slimDoctype": null,
56 "lineContinuation": null
57 };
58 var closing = {
59 "{": "}",
60 "[": "]",
61 "(": ")"
62 };
63
64 var nameStartChar = "_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
65 var nameChar = nameStartChar + "\\-0-9\xB7\u0300-\u036F\u203F-\u2040";
66 var nameRegexp = new RegExp("^[:"+nameStartChar+"](?::["+nameChar+"]|["+nameChar+"]*)");
67 var attributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*(?=\\s*=)");
68 var wrappedAttributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*");
69 var classNameRegexp = /^\.-?[_a-zA-Z]+[\w\-]*/;
70 var classIdRegexp = /^#[_a-zA-Z]+[\w\-]*/;
71
72 function backup(pos, tokenize, style) {
73 var restore = function(stream, state) {
74 state.tokenize = tokenize;
75 if (stream.pos < pos) {
76 stream.pos = pos;
77 return style;
78 }
79 return state.tokenize(stream, state);
80 };
81 return function(stream, state) {
82 state.tokenize = restore;
83 return tokenize(stream, state);
84 };
85 }
86
87 function maybeBackup(stream, state, pat, offset, style) {
88 var cur = stream.current();
89 var idx = cur.search(pat);
90 if (idx > -1) {
91 state.tokenize = backup(stream.pos, state.tokenize, style);
92 stream.backUp(cur.length - idx - offset);
93 }
94 return style;
95 }
96
97 function continueLine(state, column) {
98 state.stack = {
99 parent: state.stack,
100 style: "continuation",
101 indented: column,
102 tokenize: state.line
103 };
104 state.line = state.tokenize;
105 }
106 function finishContinue(state) {
107 if (state.line == state.tokenize) {
108 state.line = state.stack.tokenize;
109 state.stack = state.stack.parent;
110 }
111 }
112
113 function lineContinuable(column, tokenize) {
114 return function(stream, state) {
115 finishContinue(state);
116 if (stream.match(/^\\$/)) {
117 continueLine(state, column);
118 return "lineContinuation";
119 }
120 var style = tokenize(stream, state);
121 if (stream.eol() && stream.current().match(/(?:^|[^\\])(?:\\\\)*\\$/)) {
122 stream.backUp(1);
123 }
124 return style;
125 };
126 }
127 function commaContinuable(column, tokenize) {
128 return function(stream, state) {
129 finishContinue(state);
130 var style = tokenize(stream, state);
131 if (stream.eol() && stream.current().match(/,$/)) {
132 continueLine(state, column);
133 }
134 return style;
135 };
136 }
137
138 function rubyInQuote(endQuote, tokenize) {
139 // TODO: add multi line support
140 return function(stream, state) {
141 var ch = stream.peek();
142 if (ch == endQuote && state.rubyState.tokenize.length == 1) {
143 // step out of ruby context as it seems to complete processing all the braces
144 stream.next();
145 state.tokenize = tokenize;
146 return "closeAttributeTag";
147 } else {
148 return ruby(stream, state);
149 }
150 };
151 }
152 function startRubySplat(tokenize) {
153 var rubyState;
154 var runSplat = function(stream, state) {
155 if (state.rubyState.tokenize.length == 1 && !state.rubyState.context.prev) {
156 stream.backUp(1);
157 if (stream.eatSpace()) {
158 state.rubyState = rubyState;
159 state.tokenize = tokenize;
160 return tokenize(stream, state);
161 }
162 stream.next();
163 }
164 return ruby(stream, state);
165 };
166 return function(stream, state) {
167 rubyState = state.rubyState;
168 state.rubyState = rubyMode.startState();
169 state.tokenize = runSplat;
170 return ruby(stream, state);
171 };
172 }
173
174 function ruby(stream, state) {
175 return rubyMode.token(stream, state.rubyState);
176 }
177
178 function htmlLine(stream, state) {
179 if (stream.match(/^\\$/)) {
180 return "lineContinuation";
181 }
182 return html(stream, state);
183 }
184 function html(stream, state) {
185 if (stream.match(/^#\{/)) {
186 state.tokenize = rubyInQuote("}", state.tokenize);
187 return null;
188 }
189 return maybeBackup(stream, state, /[^\\]#\{/, 1, htmlMode.token(stream, state.htmlState));
190 }
191
192 function startHtmlLine(lastTokenize) {
193 return function(stream, state) {
194 var style = htmlLine(stream, state);
195 if (stream.eol()) state.tokenize = lastTokenize;
196 return style;
197 };
198 }
199
200 function startHtmlMode(stream, state, offset) {
201 state.stack = {
202 parent: state.stack,
203 style: "html",
204 indented: stream.column() + offset, // pipe + space
205 tokenize: state.line
206 };
207 state.line = state.tokenize = html;
208 return null;
209 }
210
211 function comment(stream, state) {
212 stream.skipToEnd();
213 return state.stack.style;
214 }
215
216 function commentMode(stream, state) {
217 state.stack = {
218 parent: state.stack,
219 style: "comment",
220 indented: state.indented + 1,
221 tokenize: state.line
222 };
223 state.line = comment;
224 return comment(stream, state);
225 }
226
227 function attributeWrapper(stream, state) {
228 if (stream.eat(state.stack.endQuote)) {
229 state.line = state.stack.line;
230 state.tokenize = state.stack.tokenize;
231 state.stack = state.stack.parent;
232 return null;
233 }
234 if (stream.match(wrappedAttributeNameRegexp)) {
235 state.tokenize = attributeWrapperAssign;
236 return "slimAttribute";
237 }
238 stream.next();
239 return null;
240 }
241 function attributeWrapperAssign(stream, state) {
242 if (stream.match(/^==?/)) {
243 state.tokenize = attributeWrapperValue;
244 return null;
245 }
246 return attributeWrapper(stream, state);
247 }
248 function attributeWrapperValue(stream, state) {
249 var ch = stream.peek();
250 if (ch == '"' || ch == "\'") {
251 state.tokenize = readQuoted(ch, "string", true, false, attributeWrapper);
252 stream.next();
253 return state.tokenize(stream, state);
254 }
255 if (ch == '[') {
256 return startRubySplat(attributeWrapper)(stream, state);
257 }
258 if (stream.match(/^(true|false|nil)\b/)) {
259 state.tokenize = attributeWrapper;
260 return "keyword";
261 }
262 return startRubySplat(attributeWrapper)(stream, state);
263 }
264
265 function startAttributeWrapperMode(state, endQuote, tokenize) {
266 state.stack = {
267 parent: state.stack,
268 style: "wrapper",
269 indented: state.indented + 1,
270 tokenize: tokenize,
271 line: state.line,
272 endQuote: endQuote
273 };
274 state.line = state.tokenize = attributeWrapper;
275 return null;
276 }
277
278 function sub(stream, state) {
279 if (stream.match(/^#\{/)) {
280 state.tokenize = rubyInQuote("}", state.tokenize);
281 return null;
282 }
283 var subStream = new CodeMirror.StringStream(stream.string.slice(state.stack.indented), stream.tabSize);
284 subStream.pos = stream.pos - state.stack.indented;
285 subStream.start = stream.start - state.stack.indented;
286 subStream.lastColumnPos = stream.lastColumnPos - state.stack.indented;
287 subStream.lastColumnValue = stream.lastColumnValue - state.stack.indented;
288 var style = state.subMode.token(subStream, state.subState);
289 stream.pos = subStream.pos + state.stack.indented;
290 return style;
291 }
292 function firstSub(stream, state) {
293 state.stack.indented = stream.column();
294 state.line = state.tokenize = sub;
295 return state.tokenize(stream, state);
296 }
297
298 function createMode(mode) {
299 var query = embedded[mode];
300 var spec = CodeMirror.mimeModes[query];
301 if (spec) {
302 return CodeMirror.getMode(config, spec);
303 }
304 var factory = CodeMirror.modes[query];
305 if (factory) {
306 return factory(config, {name: query});
307 }
308 return CodeMirror.getMode(config, "null");
309 }
310
311 function getMode(mode) {
312 if (!modes.hasOwnProperty(mode)) {
313 return modes[mode] = createMode(mode);
314 }
315 return modes[mode];
316 }
317
318 function startSubMode(mode, state) {
319 var subMode = getMode(mode);
320 var subState = subMode.startState && subMode.startState();
321
322 state.subMode = subMode;
323 state.subState = subState;
324
325 state.stack = {
326 parent: state.stack,
327 style: "sub",
328 indented: state.indented + 1,
329 tokenize: state.line
330 };
331 state.line = state.tokenize = firstSub;
332 return "slimSubmode";
333 }
334
335 function doctypeLine(stream, _state) {
336 stream.skipToEnd();
337 return "slimDoctype";
338 }
339
340 function startLine(stream, state) {
341 var ch = stream.peek();
342 if (ch == '<') {
343 return (state.tokenize = startHtmlLine(state.tokenize))(stream, state);
344 }
345 if (stream.match(/^[|']/)) {
346 return startHtmlMode(stream, state, 1);
347 }
348 if (stream.match(/^\/(!|\[\w+])?/)) {
349 return commentMode(stream, state);
350 }
351 if (stream.match(/^(-|==?[<>]?)/)) {
352 state.tokenize = lineContinuable(stream.column(), commaContinuable(stream.column(), ruby));
353 return "slimSwitch";
354 }
355 if (stream.match(/^doctype\b/)) {
356 state.tokenize = doctypeLine;
357 return "keyword";
358 }
359
360 var m = stream.match(embeddedRegexp);
361 if (m) {
362 return startSubMode(m[1], state);
363 }
364
365 return slimTag(stream, state);
366 }
367
368 function slim(stream, state) {
369 if (state.startOfLine) {
370 return startLine(stream, state);
371 }
372 return slimTag(stream, state);
373 }
374
375 function slimTag(stream, state) {
376 if (stream.eat('*')) {
377 state.tokenize = startRubySplat(slimTagExtras);
378 return null;
379 }
380 if (stream.match(nameRegexp)) {
381 state.tokenize = slimTagExtras;
382 return "slimTag";
383 }
384 return slimClass(stream, state);
385 }
386 function slimTagExtras(stream, state) {
387 if (stream.match(/^(<>?|><?)/)) {
388 state.tokenize = slimClass;
389 return null;
390 }
391 return slimClass(stream, state);
392 }
393 function slimClass(stream, state) {
394 if (stream.match(classIdRegexp)) {
395 state.tokenize = slimClass;
396 return "slimId";
397 }
398 if (stream.match(classNameRegexp)) {
399 state.tokenize = slimClass;
400 return "slimClass";
401 }
402 return slimAttribute(stream, state);
403 }
404 function slimAttribute(stream, state) {
405 if (stream.match(/^([\[\{\(])/)) {
406 return startAttributeWrapperMode(state, closing[RegExp.$1], slimAttribute);
407 }
408 if (stream.match(attributeNameRegexp)) {
409 state.tokenize = slimAttributeAssign;
410 return "slimAttribute";
411 }
412 if (stream.peek() == '*') {
413 stream.next();
414 state.tokenize = startRubySplat(slimContent);
415 return null;
416 }
417 return slimContent(stream, state);
418 }
419 function slimAttributeAssign(stream, state) {
420 if (stream.match(/^==?/)) {
421 state.tokenize = slimAttributeValue;
422 return null;
423 }
424 // should never happen, because of forward lookup
425 return slimAttribute(stream, state);
426 }
427
428 function slimAttributeValue(stream, state) {
429 var ch = stream.peek();
430 if (ch == '"' || ch == "\'") {
431 state.tokenize = readQuoted(ch, "string", true, false, slimAttribute);
432 stream.next();
433 return state.tokenize(stream, state);
434 }
435 if (ch == '[') {
436 return startRubySplat(slimAttribute)(stream, state);
437 }
438 if (ch == ':') {
439 return startRubySplat(slimAttributeSymbols)(stream, state);
440 }
441 if (stream.match(/^(true|false|nil)\b/)) {
442 state.tokenize = slimAttribute;
443 return "keyword";
444 }
445 return startRubySplat(slimAttribute)(stream, state);
446 }
447 function slimAttributeSymbols(stream, state) {
448 stream.backUp(1);
449 if (stream.match(/^[^\s],(?=:)/)) {
450 state.tokenize = startRubySplat(slimAttributeSymbols);
451 return null;
452 }
453 stream.next();
454 return slimAttribute(stream, state);
455 }
456 function readQuoted(quote, style, embed, unescaped, nextTokenize) {
457 return function(stream, state) {
458 finishContinue(state);
459 var fresh = stream.current().length == 0;
460 if (stream.match(/^\\$/, fresh)) {
461 if (!fresh) return style;
462 continueLine(state, state.indented);
463 return "lineContinuation";
464 }
465 if (stream.match(/^#\{/, fresh)) {
466 if (!fresh) return style;
467 state.tokenize = rubyInQuote("}", state.tokenize);
468 return null;
469 }
470 var escaped = false, ch;
471 while ((ch = stream.next()) != null) {
472 if (ch == quote && (unescaped || !escaped)) {
473 state.tokenize = nextTokenize;
474 break;
475 }
476 if (embed && ch == "#" && !escaped) {
477 if (stream.eat("{")) {
478 stream.backUp(2);
479 break;
480 }
481 }
482 escaped = !escaped && ch == "\\";
483 }
484 if (stream.eol() && escaped) {
485 stream.backUp(1);
486 }
487 return style;
488 };
489 }
490 function slimContent(stream, state) {
491 if (stream.match(/^==?/)) {
492 state.tokenize = ruby;
493 return "slimSwitch";
494 }
495 if (stream.match(/^\/$/)) { // tag close hint
496 state.tokenize = slim;
497 return null;
498 }
499 if (stream.match(/^:/)) { // inline tag
500 state.tokenize = slimTag;
501 return "slimSwitch";
502 }
503 startHtmlMode(stream, state, 0);
504 return state.tokenize(stream, state);
505 }
506
507 var mode = {
508 // default to html mode
509 startState: function() {
510 var htmlState = htmlMode.startState();
511 var rubyState = rubyMode.startState();
512 return {
513 htmlState: htmlState,
514 rubyState: rubyState,
515 stack: null,
516 last: null,
517 tokenize: slim,
518 line: slim,
519 indented: 0
520 };
521 },
522
523 copyState: function(state) {
524 return {
525 htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
526 rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
527 subMode: state.subMode,
528 subState: state.subMode && CodeMirror.copyState(state.subMode, state.subState),
529 stack: state.stack,
530 last: state.last,
531 tokenize: state.tokenize,
532 line: state.line
533 };
534 },
535
536 token: function(stream, state) {
537 if (stream.sol()) {
538 state.indented = stream.indentation();
539 state.startOfLine = true;
540 state.tokenize = state.line;
541 while (state.stack && state.stack.indented > state.indented && state.last != "slimSubmode") {
542 state.line = state.tokenize = state.stack.tokenize;
543 state.stack = state.stack.parent;
544 state.subMode = null;
545 state.subState = null;
546 }
547 }
548 if (stream.eatSpace()) return null;
549 var style = state.tokenize(stream, state);
550 state.startOfLine = false;
551 if (style) state.last = style;
552 return styleMap.hasOwnProperty(style) ? styleMap[style] : style;
553 },
554
555 blankLine: function(state) {
556 if (state.subMode && state.subMode.blankLine) {
557 return state.subMode.blankLine(state.subState);
558 }
559 },
560
561 innerMode: function(state) {
562 if (state.subMode) return {state: state.subState, mode: state.subMode};
563 return {state: state, mode: mode};
564 }
565
566 //indent: function(state) {
567 // return state.indented;
568 //}
569 };
570 return mode;
571 }, "htmlmixed", "ruby");
572
573 CodeMirror.defineMIME("text/x-slim", "slim");
574 CodeMirror.defineMIME("application/x-slim", "slim");
575 });
@@ -1,168 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('smalltalk', function(config) {
15
16 var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
17 var keywords = /true|false|nil|self|super|thisContext/;
18
19 var Context = function(tokenizer, parent) {
20 this.next = tokenizer;
21 this.parent = parent;
22 };
23
24 var Token = function(name, context, eos) {
25 this.name = name;
26 this.context = context;
27 this.eos = eos;
28 };
29
30 var State = function() {
31 this.context = new Context(next, null);
32 this.expectVariable = true;
33 this.indentation = 0;
34 this.userIndentationDelta = 0;
35 };
36
37 State.prototype.userIndent = function(indentation) {
38 this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
39 };
40
41 var next = function(stream, context, state) {
42 var token = new Token(null, context, false);
43 var aChar = stream.next();
44
45 if (aChar === '"') {
46 token = nextComment(stream, new Context(nextComment, context));
47
48 } else if (aChar === '\'') {
49 token = nextString(stream, new Context(nextString, context));
50
51 } else if (aChar === '#') {
52 if (stream.peek() === '\'') {
53 stream.next();
54 token = nextSymbol(stream, new Context(nextSymbol, context));
55 } else {
56 if (stream.eatWhile(/[^\s.{}\[\]()]/))
57 token.name = 'string-2';
58 else
59 token.name = 'meta';
60 }
61
62 } else if (aChar === '$') {
63 if (stream.next() === '<') {
64 stream.eatWhile(/[^\s>]/);
65 stream.next();
66 }
67 token.name = 'string-2';
68
69 } else if (aChar === '|' && state.expectVariable) {
70 token.context = new Context(nextTemporaries, context);
71
72 } else if (/[\[\]{}()]/.test(aChar)) {
73 token.name = 'bracket';
74 token.eos = /[\[{(]/.test(aChar);
75
76 if (aChar === '[') {
77 state.indentation++;
78 } else if (aChar === ']') {
79 state.indentation = Math.max(0, state.indentation - 1);
80 }
81
82 } else if (specialChars.test(aChar)) {
83 stream.eatWhile(specialChars);
84 token.name = 'operator';
85 token.eos = aChar !== ';'; // ; cascaded message expression
86
87 } else if (/\d/.test(aChar)) {
88 stream.eatWhile(/[\w\d]/);
89 token.name = 'number';
90
91 } else if (/[\w_]/.test(aChar)) {
92 stream.eatWhile(/[\w\d_]/);
93 token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
94
95 } else {
96 token.eos = state.expectVariable;
97 }
98
99 return token;
100 };
101
102 var nextComment = function(stream, context) {
103 stream.eatWhile(/[^"]/);
104 return new Token('comment', stream.eat('"') ? context.parent : context, true);
105 };
106
107 var nextString = function(stream, context) {
108 stream.eatWhile(/[^']/);
109 return new Token('string', stream.eat('\'') ? context.parent : context, false);
110 };
111
112 var nextSymbol = function(stream, context) {
113 stream.eatWhile(/[^']/);
114 return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
115 };
116
117 var nextTemporaries = function(stream, context) {
118 var token = new Token(null, context, false);
119 var aChar = stream.next();
120
121 if (aChar === '|') {
122 token.context = context.parent;
123 token.eos = true;
124
125 } else {
126 stream.eatWhile(/[^|]/);
127 token.name = 'variable';
128 }
129
130 return token;
131 };
132
133 return {
134 startState: function() {
135 return new State;
136 },
137
138 token: function(stream, state) {
139 state.userIndent(stream.indentation());
140
141 if (stream.eatSpace()) {
142 return null;
143 }
144
145 var token = state.context.next(stream, state.context, state);
146 state.context = token.context;
147 state.expectVariable = token.eos;
148
149 return token.name;
150 },
151
152 blankLine: function(state) {
153 state.userIndent(0);
154 },
155
156 indent: function(state, textAfter) {
157 var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
158 return (state.indentation + i) * config.indentUnit;
159 },
160
161 electricChars: ']'
162 };
163
164 });
165
166 CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});
167
168 });
@@ -1,221 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * Smarty 2 and 3 mode.
6 */
7
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15 })(function(CodeMirror) {
16 "use strict";
17
18 CodeMirror.defineMode("smarty", function(config) {
19 "use strict";
20
21 // our default settings; check to see if they're overridden
22 var settings = {
23 rightDelimiter: '}',
24 leftDelimiter: '{',
25 smartyVersion: 2 // for backward compatibility
26 };
27 if (config.hasOwnProperty("leftDelimiter")) {
28 settings.leftDelimiter = config.leftDelimiter;
29 }
30 if (config.hasOwnProperty("rightDelimiter")) {
31 settings.rightDelimiter = config.rightDelimiter;
32 }
33 if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
34 settings.smartyVersion = 3;
35 }
36
37 var keyFunctions = ["debug", "extends", "function", "include", "literal"];
38 var last;
39 var regs = {
40 operatorChars: /[+\-*&%=<>!?]/,
41 validIdentifier: /[a-zA-Z0-9_]/,
42 stringChar: /['"]/
43 };
44
45 var helpers = {
46 cont: function(style, lastType) {
47 last = lastType;
48 return style;
49 },
50 chain: function(stream, state, parser) {
51 state.tokenize = parser;
52 return parser(stream, state);
53 }
54 };
55
56
57 // our various parsers
58 var parsers = {
59
60 // the main tokenizer
61 tokenizer: function(stream, state) {
62 if (stream.match(settings.leftDelimiter, true)) {
63 if (stream.eat("*")) {
64 return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
65 } else {
66 // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
67 state.depth++;
68 var isEol = stream.eol();
69 var isFollowedByWhitespace = /\s/.test(stream.peek());
70 if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
71 state.depth--;
72 return null;
73 } else {
74 state.tokenize = parsers.smarty;
75 last = "startTag";
76 return "tag";
77 }
78 }
79 } else {
80 stream.next();
81 return null;
82 }
83 },
84
85 // parsing Smarty content
86 smarty: function(stream, state) {
87 if (stream.match(settings.rightDelimiter, true)) {
88 if (settings.smartyVersion === 3) {
89 state.depth--;
90 if (state.depth <= 0) {
91 state.tokenize = parsers.tokenizer;
92 }
93 } else {
94 state.tokenize = parsers.tokenizer;
95 }
96 return helpers.cont("tag", null);
97 }
98
99 if (stream.match(settings.leftDelimiter, true)) {
100 state.depth++;
101 return helpers.cont("tag", "startTag");
102 }
103
104 var ch = stream.next();
105 if (ch == "$") {
106 stream.eatWhile(regs.validIdentifier);
107 return helpers.cont("variable-2", "variable");
108 } else if (ch == "|") {
109 return helpers.cont("operator", "pipe");
110 } else if (ch == ".") {
111 return helpers.cont("operator", "property");
112 } else if (regs.stringChar.test(ch)) {
113 state.tokenize = parsers.inAttribute(ch);
114 return helpers.cont("string", "string");
115 } else if (regs.operatorChars.test(ch)) {
116 stream.eatWhile(regs.operatorChars);
117 return helpers.cont("operator", "operator");
118 } else if (ch == "[" || ch == "]") {
119 return helpers.cont("bracket", "bracket");
120 } else if (ch == "(" || ch == ")") {
121 return helpers.cont("bracket", "operator");
122 } else if (/\d/.test(ch)) {
123 stream.eatWhile(/\d/);
124 return helpers.cont("number", "number");
125 } else {
126
127 if (state.last == "variable") {
128 if (ch == "@") {
129 stream.eatWhile(regs.validIdentifier);
130 return helpers.cont("property", "property");
131 } else if (ch == "|") {
132 stream.eatWhile(regs.validIdentifier);
133 return helpers.cont("qualifier", "modifier");
134 }
135 } else if (state.last == "pipe") {
136 stream.eatWhile(regs.validIdentifier);
137 return helpers.cont("qualifier", "modifier");
138 } else if (state.last == "whitespace") {
139 stream.eatWhile(regs.validIdentifier);
140 return helpers.cont("attribute", "modifier");
141 } if (state.last == "property") {
142 stream.eatWhile(regs.validIdentifier);
143 return helpers.cont("property", null);
144 } else if (/\s/.test(ch)) {
145 last = "whitespace";
146 return null;
147 }
148
149 var str = "";
150 if (ch != "/") {
151 str += ch;
152 }
153 var c = null;
154 while (c = stream.eat(regs.validIdentifier)) {
155 str += c;
156 }
157 for (var i=0, j=keyFunctions.length; i<j; i++) {
158 if (keyFunctions[i] == str) {
159 return helpers.cont("keyword", "keyword");
160 }
161 }
162 if (/\s/.test(ch)) {
163 return null;
164 }
165 return helpers.cont("tag", "tag");
166 }
167 },
168
169 inAttribute: function(quote) {
170 return function(stream, state) {
171 var prevChar = null;
172 var currChar = null;
173 while (!stream.eol()) {
174 currChar = stream.peek();
175 if (stream.next() == quote && prevChar !== '\\') {
176 state.tokenize = parsers.smarty;
177 break;
178 }
179 prevChar = currChar;
180 }
181 return "string";
182 };
183 },
184
185 inBlock: function(style, terminator) {
186 return function(stream, state) {
187 while (!stream.eol()) {
188 if (stream.match(terminator)) {
189 state.tokenize = parsers.tokenizer;
190 break;
191 }
192 stream.next();
193 }
194 return style;
195 };
196 }
197 };
198
199
200 // the public API for CodeMirror
201 return {
202 startState: function() {
203 return {
204 tokenize: parsers.tokenizer,
205 mode: "smarty",
206 last: null,
207 depth: 0
208 };
209 },
210 token: function(stream, state) {
211 var style = state.tokenize(stream, state);
212 state.last = last;
213 return style;
214 },
215 electricChars: ""
216 };
217 });
218
219 CodeMirror.defineMIME("text/x-smarty", "smarty");
220
221 });
@@ -1,197 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /**
5 * @file smartymixed.js
6 * @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
7 * @author Ruslan Osmanov <rrosmanov at gmail dot com>
8 * @version 3.0
9 * @date 05.07.2013
10 */
11
12 // Warning: Don't base other modes on this one. This here is a
13 // terrible way to write a mixed mode.
14
15 (function(mod) {
16 if (typeof exports == "object" && typeof module == "object") // CommonJS
17 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../smarty/smarty"));
18 else if (typeof define == "function" && define.amd) // AMD
19 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../smarty/smarty"], mod);
20 else // Plain browser env
21 mod(CodeMirror);
22 })(function(CodeMirror) {
23 "use strict";
24
25 CodeMirror.defineMode("smartymixed", function(config) {
26 var htmlMixedMode = CodeMirror.getMode(config, "htmlmixed");
27 var smartyMode = CodeMirror.getMode(config, "smarty");
28
29 var settings = {
30 rightDelimiter: '}',
31 leftDelimiter: '{'
32 };
33
34 if (config.hasOwnProperty("leftDelimiter")) {
35 settings.leftDelimiter = config.leftDelimiter;
36 }
37 if (config.hasOwnProperty("rightDelimiter")) {
38 settings.rightDelimiter = config.rightDelimiter;
39 }
40
41 function reEsc(str) { return str.replace(/[^\s\w]/g, "\\$&"); }
42
43 var reLeft = reEsc(settings.leftDelimiter), reRight = reEsc(settings.rightDelimiter);
44 var regs = {
45 smartyComment: new RegExp("^" + reRight + "\\*"),
46 literalOpen: new RegExp(reLeft + "literal" + reRight),
47 literalClose: new RegExp(reLeft + "\/literal" + reRight),
48 hasLeftDelimeter: new RegExp(".*" + reLeft),
49 htmlHasLeftDelimeter: new RegExp("[^<>]*" + reLeft)
50 };
51
52 var helpers = {
53 chain: function(stream, state, parser) {
54 state.tokenize = parser;
55 return parser(stream, state);
56 },
57
58 cleanChain: function(stream, state, parser) {
59 state.tokenize = null;
60 state.localState = null;
61 state.localMode = null;
62 return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
63 },
64
65 maybeBackup: function(stream, pat, style) {
66 var cur = stream.current();
67 var close = cur.search(pat),
68 m;
69 if (close > - 1) stream.backUp(cur.length - close);
70 else if (m = cur.match(/<\/?$/)) {
71 stream.backUp(cur.length);
72 if (!stream.match(pat, false)) stream.match(cur[0]);
73 }
74 return style;
75 }
76 };
77
78 var parsers = {
79 html: function(stream, state) {
80 var htmlTagName = state.htmlMixedState.htmlState.context && state.htmlMixedState.htmlState.context.tagName
81 ? state.htmlMixedState.htmlState.context.tagName
82 : null;
83
84 if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && htmlTagName === null) {
85 state.tokenize = parsers.smarty;
86 state.localMode = smartyMode;
87 state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
88 return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
89 } else if (!state.inLiteral && stream.match(settings.leftDelimiter, false)) {
90 state.tokenize = parsers.smarty;
91 state.localMode = smartyMode;
92 state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
93 return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
94 }
95 return htmlMixedMode.token(stream, state.htmlMixedState);
96 },
97
98 smarty: function(stream, state) {
99 if (stream.match(settings.leftDelimiter, false)) {
100 if (stream.match(regs.smartyComment, false)) {
101 return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
102 }
103 } else if (stream.match(settings.rightDelimiter, false)) {
104 stream.eat(settings.rightDelimiter);
105 state.tokenize = parsers.html;
106 state.localMode = htmlMixedMode;
107 state.localState = state.htmlMixedState;
108 return "tag";
109 }
110
111 return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
112 },
113
114 inBlock: function(style, terminator) {
115 return function(stream, state) {
116 while (!stream.eol()) {
117 if (stream.match(terminator)) {
118 helpers.cleanChain(stream, state, "");
119 break;
120 }
121 stream.next();
122 }
123 return style;
124 };
125 }
126 };
127
128 return {
129 startState: function() {
130 var state = htmlMixedMode.startState();
131 return {
132 token: parsers.html,
133 localMode: null,
134 localState: null,
135 htmlMixedState: state,
136 tokenize: null,
137 inLiteral: false
138 };
139 },
140
141 copyState: function(state) {
142 var local = null, tok = (state.tokenize || state.token);
143 if (state.localState) {
144 local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
145 }
146 return {
147 token: state.token,
148 tokenize: state.tokenize,
149 localMode: state.localMode,
150 localState: local,
151 htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
152 inLiteral: state.inLiteral
153 };
154 },
155
156 token: function(stream, state) {
157 if (stream.match(settings.leftDelimiter, false)) {
158 if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
159 state.inLiteral = true;
160 return "keyword";
161 } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
162 state.inLiteral = false;
163 return "keyword";
164 }
165 }
166 if (state.inLiteral && state.localState != state.htmlMixedState) {
167 state.tokenize = parsers.html;
168 state.localMode = htmlMixedMode;
169 state.localState = state.htmlMixedState;
170 }
171
172 var style = (state.tokenize || state.token)(stream, state);
173 return style;
174 },
175
176 indent: function(state, textAfter) {
177 if (state.localMode == smartyMode
178 || (state.inLiteral && !state.localMode)
179 || regs.hasLeftDelimeter.test(textAfter)) {
180 return CodeMirror.Pass;
181 }
182 return htmlMixedMode.indent(state.htmlMixedState, textAfter);
183 },
184
185 innerMode: function(state) {
186 return {
187 state: state.localState || state.htmlMixedState,
188 mode: state.localMode || htmlMixedMode
189 };
190 }
191 };
192 }, "htmlmixed", "smarty");
193
194 CodeMirror.defineMIME("text/x-smarty", "smartymixed");
195 // vim: et ts=2 sts=2 sw=2
196
197 });
@@ -1,104 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("solr", function() {
15 "use strict";
16
17 var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\^\"\\]/;
18 var isOperatorChar = /[\|\!\+\-\*\?\~\^\&]/;
19 var isOperatorString = /^(OR|AND|NOT|TO)$/i;
20
21 function isNumber(word) {
22 return parseFloat(word, 10).toString() === word;
23 }
24
25 function tokenString(quote) {
26 return function(stream, state) {
27 var escaped = false, next;
28 while ((next = stream.next()) != null) {
29 if (next == quote && !escaped) break;
30 escaped = !escaped && next == "\\";
31 }
32
33 if (!escaped) state.tokenize = tokenBase;
34 return "string";
35 };
36 }
37
38 function tokenOperator(operator) {
39 return function(stream, state) {
40 var style = "operator";
41 if (operator == "+")
42 style += " positive";
43 else if (operator == "-")
44 style += " negative";
45 else if (operator == "|")
46 stream.eat(/\|/);
47 else if (operator == "&")
48 stream.eat(/\&/);
49 else if (operator == "^")
50 style += " boost";
51
52 state.tokenize = tokenBase;
53 return style;
54 };
55 }
56
57 function tokenWord(ch) {
58 return function(stream, state) {
59 var word = ch;
60 while ((ch = stream.peek()) && ch.match(isStringChar) != null) {
61 word += stream.next();
62 }
63
64 state.tokenize = tokenBase;
65 if (isOperatorString.test(word))
66 return "operator";
67 else if (isNumber(word))
68 return "number";
69 else if (stream.peek() == ":")
70 return "field";
71 else
72 return "string";
73 };
74 }
75
76 function tokenBase(stream, state) {
77 var ch = stream.next();
78 if (ch == '"')
79 state.tokenize = tokenString(ch);
80 else if (isOperatorChar.test(ch))
81 state.tokenize = tokenOperator(ch);
82 else if (isStringChar.test(ch))
83 state.tokenize = tokenWord(ch);
84
85 return (state.tokenize != tokenBase) ? state.tokenize(stream, state) : null;
86 }
87
88 return {
89 startState: function() {
90 return {
91 tokenize: tokenBase
92 };
93 },
94
95 token: function(stream, state) {
96 if (stream.eatSpace()) return null;
97 return state.tokenize(stream, state);
98 }
99 };
100 });
101
102 CodeMirror.defineMIME("text/x-solr", "solr");
103
104 });
@@ -1,160 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("sparql", function(config) {
15 var indentUnit = config.indentUnit;
16 var curPunc;
17
18 function wordRegexp(words) {
19 return new RegExp("^(?:" + words.join("|") + ")$", "i");
20 }
21 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
22 "isblank", "isliteral", "a"]);
23 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
24 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
25 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
26 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
27 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
28 var operatorChars = /[*+\-<>=&|]/;
29
30 function tokenBase(stream, state) {
31 var ch = stream.next();
32 curPunc = null;
33 if (ch == "$" || ch == "?") {
34 stream.match(/^[\w\d]*/);
35 return "variable-2";
36 }
37 else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
38 stream.match(/^[^\s\u00a0>]*>?/);
39 return "atom";
40 }
41 else if (ch == "\"" || ch == "'") {
42 state.tokenize = tokenLiteral(ch);
43 return state.tokenize(stream, state);
44 }
45 else if (/[{}\(\),\.;\[\]]/.test(ch)) {
46 curPunc = ch;
47 return null;
48 }
49 else if (ch == "#") {
50 stream.skipToEnd();
51 return "comment";
52 }
53 else if (operatorChars.test(ch)) {
54 stream.eatWhile(operatorChars);
55 return null;
56 }
57 else if (ch == ":") {
58 stream.eatWhile(/[\w\d\._\-]/);
59 return "atom";
60 }
61 else {
62 stream.eatWhile(/[_\w\d]/);
63 if (stream.eat(":")) {
64 stream.eatWhile(/[\w\d_\-]/);
65 return "atom";
66 }
67 var word = stream.current();
68 if (ops.test(word))
69 return null;
70 else if (keywords.test(word))
71 return "keyword";
72 else
73 return "variable";
74 }
75 }
76
77 function tokenLiteral(quote) {
78 return function(stream, state) {
79 var escaped = false, ch;
80 while ((ch = stream.next()) != null) {
81 if (ch == quote && !escaped) {
82 state.tokenize = tokenBase;
83 break;
84 }
85 escaped = !escaped && ch == "\\";
86 }
87 return "string";
88 };
89 }
90
91 function pushContext(state, type, col) {
92 state.context = {prev: state.context, indent: state.indent, col: col, type: type};
93 }
94 function popContext(state) {
95 state.indent = state.context.indent;
96 state.context = state.context.prev;
97 }
98
99 return {
100 startState: function() {
101 return {tokenize: tokenBase,
102 context: null,
103 indent: 0,
104 col: 0};
105 },
106
107 token: function(stream, state) {
108 if (stream.sol()) {
109 if (state.context && state.context.align == null) state.context.align = false;
110 state.indent = stream.indentation();
111 }
112 if (stream.eatSpace()) return null;
113 var style = state.tokenize(stream, state);
114
115 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
116 state.context.align = true;
117 }
118
119 if (curPunc == "(") pushContext(state, ")", stream.column());
120 else if (curPunc == "[") pushContext(state, "]", stream.column());
121 else if (curPunc == "{") pushContext(state, "}", stream.column());
122 else if (/[\]\}\)]/.test(curPunc)) {
123 while (state.context && state.context.type == "pattern") popContext(state);
124 if (state.context && curPunc == state.context.type) popContext(state);
125 }
126 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
127 else if (/atom|string|variable/.test(style) && state.context) {
128 if (/[\}\]]/.test(state.context.type))
129 pushContext(state, "pattern", stream.column());
130 else if (state.context.type == "pattern" && !state.context.align) {
131 state.context.align = true;
132 state.context.col = stream.column();
133 }
134 }
135
136 return style;
137 },
138
139 indent: function(state, textAfter) {
140 var firstChar = textAfter && textAfter.charAt(0);
141 var context = state.context;
142 if (/[\]\}]/.test(firstChar))
143 while (context && context.type == "pattern") context = context.prev;
144
145 var closing = context && firstChar == context.type;
146 if (!context)
147 return 0;
148 else if (context.type == "pattern")
149 return context.col;
150 else if (context.align)
151 return context.col + (closing ? 0 : 1);
152 else
153 return context.indent + (closing ? 0 : indentUnit);
154 }
155 };
156 });
157
158 CodeMirror.defineMIME("application/x-sparql-query", "sparql");
159
160 });
@@ -1,393 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("sql", function(config, parserConfig) {
15 "use strict";
16
17 var client = parserConfig.client || {},
18 atoms = parserConfig.atoms || {"false": true, "true": true, "null": true},
19 builtin = parserConfig.builtin || {},
20 keywords = parserConfig.keywords || {},
21 operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
22 support = parserConfig.support || {},
23 hooks = parserConfig.hooks || {},
24 dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true};
25
26 function tokenBase(stream, state) {
27 var ch = stream.next();
28
29 // call hooks from the mime type
30 if (hooks[ch]) {
31 var result = hooks[ch](stream, state);
32 if (result !== false) return result;
33 }
34
35 if (support.hexNumber == true &&
36 ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
37 || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
38 // hex
39 // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
40 return "number";
41 } else if (support.binaryNumber == true &&
42 (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
43 || (ch == "0" && stream.match(/^b[01]+/)))) {
44 // bitstring
45 // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
46 return "number";
47 } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
48 // numbers
49 // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
50 stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
51 support.decimallessFloat == true && stream.eat('.');
52 return "number";
53 } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
54 // placeholders
55 return "variable-3";
56 } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
57 // strings
58 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
59 state.tokenize = tokenLiteral(ch);
60 return state.tokenize(stream, state);
61 } else if ((((support.nCharCast == true && (ch == "n" || ch == "N"))
62 || (support.charsetCast == true && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
63 && (stream.peek() == "'" || stream.peek() == '"'))) {
64 // charset casting: _utf8'str', N'str', n'str'
65 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
66 return "keyword";
67 } else if (/^[\(\),\;\[\]]/.test(ch)) {
68 // no highlightning
69 return null;
70 } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
71 // 1-line comment
72 stream.skipToEnd();
73 return "comment";
74 } else if ((support.commentHash && ch == "#")
75 || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
76 // 1-line comments
77 // ref: https://kb.askmonty.org/en/comment-syntax/
78 stream.skipToEnd();
79 return "comment";
80 } else if (ch == "/" && stream.eat("*")) {
81 // multi-line comments
82 // ref: https://kb.askmonty.org/en/comment-syntax/
83 state.tokenize = tokenComment;
84 return state.tokenize(stream, state);
85 } else if (ch == ".") {
86 // .1 for 0.1
87 if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
88 return "number";
89 }
90 // .table_name (ODBC)
91 // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
92 if (support.ODBCdotTable == true && stream.match(/^[a-zA-Z_]+/)) {
93 return "variable-2";
94 }
95 } else if (operatorChars.test(ch)) {
96 // operators
97 stream.eatWhile(operatorChars);
98 return null;
99 } else if (ch == '{' &&
100 (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
101 // dates (weird ODBC syntax)
102 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
103 return "number";
104 } else {
105 stream.eatWhile(/^[_\w\d]/);
106 var word = stream.current().toLowerCase();
107 // dates (standard SQL syntax)
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(/^( )+"[^"]*"/)))
110 return "number";
111 if (atoms.hasOwnProperty(word)) return "atom";
112 if (builtin.hasOwnProperty(word)) return "builtin";
113 if (keywords.hasOwnProperty(word)) return "keyword";
114 if (client.hasOwnProperty(word)) return "string-2";
115 return null;
116 }
117 }
118
119 // 'string', with char specified in quote escaped by '\'
120 function tokenLiteral(quote) {
121 return function(stream, state) {
122 var escaped = false, ch;
123 while ((ch = stream.next()) != null) {
124 if (ch == quote && !escaped) {
125 state.tokenize = tokenBase;
126 break;
127 }
128 escaped = !escaped && ch == "\\";
129 }
130 return "string";
131 };
132 }
133 function tokenComment(stream, state) {
134 while (true) {
135 if (stream.skipTo("*")) {
136 stream.next();
137 if (stream.eat("/")) {
138 state.tokenize = tokenBase;
139 break;
140 }
141 } else {
142 stream.skipToEnd();
143 break;
144 }
145 }
146 return "comment";
147 }
148
149 function pushContext(stream, state, type) {
150 state.context = {
151 prev: state.context,
152 indent: stream.indentation(),
153 col: stream.column(),
154 type: type
155 };
156 }
157
158 function popContext(state) {
159 state.indent = state.context.indent;
160 state.context = state.context.prev;
161 }
162
163 return {
164 startState: function() {
165 return {tokenize: tokenBase, context: null};
166 },
167
168 token: function(stream, state) {
169 if (stream.sol()) {
170 if (state.context && state.context.align == null)
171 state.context.align = false;
172 }
173 if (stream.eatSpace()) return null;
174
175 var style = state.tokenize(stream, state);
176 if (style == "comment") return style;
177
178 if (state.context && state.context.align == null)
179 state.context.align = true;
180
181 var tok = stream.current();
182 if (tok == "(")
183 pushContext(stream, state, ")");
184 else if (tok == "[")
185 pushContext(stream, state, "]");
186 else if (state.context && state.context.type == tok)
187 popContext(state);
188 return style;
189 },
190
191 indent: function(state, textAfter) {
192 var cx = state.context;
193 if (!cx) return 0;
194 var closing = textAfter.charAt(0) == cx.type;
195 if (cx.align) return cx.col + (closing ? 0 : 1);
196 else return cx.indent + (closing ? 0 : config.indentUnit);
197 },
198
199 blockCommentStart: "/*",
200 blockCommentEnd: "*/",
201 lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
202 };
203 });
204
205 (function() {
206 "use strict";
207
208 // `identifier`
209 function hookIdentifier(stream) {
210 // MySQL/MariaDB identifiers
211 // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
212 var ch;
213 while ((ch = stream.next()) != null) {
214 if (ch == "`" && !stream.eat("`")) return "variable-2";
215 }
216 stream.backUp(stream.current().length - 1);
217 return stream.eatWhile(/\w/) ? "variable-2" : null;
218 }
219
220 // variable token
221 function hookVar(stream) {
222 // variables
223 // @@prefix.varName @varName
224 // varName can be quoted with ` or ' or "
225 // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
226 if (stream.eat("@")) {
227 stream.match(/^session\./);
228 stream.match(/^local\./);
229 stream.match(/^global\./);
230 }
231
232 if (stream.eat("'")) {
233 stream.match(/^.*'/);
234 return "variable-2";
235 } else if (stream.eat('"')) {
236 stream.match(/^.*"/);
237 return "variable-2";
238 } else if (stream.eat("`")) {
239 stream.match(/^.*`/);
240 return "variable-2";
241 } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
242 return "variable-2";
243 }
244 return null;
245 };
246
247 // short client keyword token
248 function hookClient(stream) {
249 // \N means NULL
250 // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
251 if (stream.eat("N")) {
252 return "atom";
253 }
254 // \g, etc
255 // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
256 return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
257 }
258
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 having in insert into is join like not on or order select set table union update values where ";
261
262 // turn a space-separated list into an array
263 function set(str) {
264 var obj = {}, words = str.split(" ");
265 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
266 return obj;
267 }
268
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", {
271 name: "sql",
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"),
274 atoms: set("false true null unknown"),
275 operatorChars: /^[*+\-%<>!=]/,
276 dateSQL: set("date time timestamp"),
277 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
278 });
279
280 CodeMirror.defineMIME("text/x-mssql", {
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"),
283 keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered"),
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"),
286 operatorChars: /^[*+\-%<>!=]/,
287 dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
288 hooks: {
289 "@": hookVar
290 }
291 });
292
293 CodeMirror.defineMIME("text/x-mysql", {
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"),
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 groupby_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"),
298 atoms: set("false true null unknown"),
299 operatorChars: /^[*+\-%<>!=&|^]/,
300 dateSQL: set("date time timestamp"),
301 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
302 hooks: {
303 "@": hookVar,
304 "`": hookIdentifier,
305 "\\": hookClient
306 }
307 });
308
309 CodeMirror.defineMIME("text/x-mariadb", {
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"),
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"),
314 atoms: set("false true null unknown"),
315 operatorChars: /^[*+\-%<>!=&|^]/,
316 dateSQL: set("date time timestamp"),
317 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
318 hooks: {
319 "@": hookVar,
320 "`": hookIdentifier,
321 "\\": hookClient
322 }
323 });
324
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
327 CodeMirror.defineMIME("text/x-cassandra", {
328 name: "sql",
329 client: { },
330 keywords: set("use select from using consistency where limit first reversed first and in insert into values using consistency ttl update set delete truncate begin batch apply create keyspace with columnfamily primary key index on drop alter type add any one quorum all local_quorum each_quorum"),
331 builtin: set("ascii bigint blob boolean counter decimal double float int text timestamp uuid varchar varint"),
332 atoms: set("false true"),
333 operatorChars: /^[<>=]/,
334 dateSQL: { },
335 support: set("commentSlashSlash decimallessFloat"),
336 hooks: { }
337 });
338
339 // this is based on Peter Raganitsch's 'plsql' mode
340 CodeMirror.defineMIME("text/x-plsql", {
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"),
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"),
345 operatorChars: /^[*+\-%<>!=~]/,
346 dateSQL: set("date time timestamp"),
347 support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
348 });
349
350 // Created to support specific hive keywords
351 CodeMirror.defineMIME("text/x-hive", {
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"),
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"),
356 operatorChars: /^[*+\-%<>!=]/,
357 dateSQL: set("date timestamp"),
358 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
359 });
360 }());
361
362 });
363
364 /*
365 How Properties of Mime Types are used by SQL Mode
366 =================================================
367
368 keywords:
369 A list of keywords you want to be highlighted.
370 functions:
371 A list of function names you want to be highlighted.
372 builtin:
373 A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
374 operatorChars:
375 All characters that must be handled as operators.
376 client:
377 Commands parsed and executed by the client (not the server).
378 support:
379 A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
380 * ODBCdotTable: .tableName
381 * zerolessFloat: .1
382 * doubleQuote
383 * nCharCast: N'string'
384 * charsetCast: _utf8'string'
385 * commentHash: use # char for comments
386 * commentSlashSlash: use // for comments
387 * commentSpaceRequired: require a space after -- for comments
388 atoms:
389 Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
390 UNKNOWN, INFINITY, UNDERFLOW, NaN...
391 dateSQL:
392 Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
393 */
@@ -1,262 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
6 * Licence: MIT
7 */
8
9 (function(mod) {
10 if (typeof exports == "object" && typeof module == "object") // CommonJS
11 mod(require("../../lib/codemirror"));
12 else if (typeof define == "function" && define.amd) // AMD
13 define(["../../lib/codemirror"], mod);
14 else // Plain browser env
15 mod(CodeMirror);
16 })(function(CodeMirror) {
17 "use strict";
18
19 CodeMirror.defineMode("stex", function() {
20 "use strict";
21
22 function pushCommand(state, command) {
23 state.cmdState.push(command);
24 }
25
26 function peekCommand(state) {
27 if (state.cmdState.length > 0) {
28 return state.cmdState[state.cmdState.length - 1];
29 } else {
30 return null;
31 }
32 }
33
34 function popCommand(state) {
35 var plug = state.cmdState.pop();
36 if (plug) {
37 plug.closeBracket();
38 }
39 }
40
41 // returns the non-default plugin closest to the end of the list
42 function getMostPowerful(state) {
43 var context = state.cmdState;
44 for (var i = context.length - 1; i >= 0; i--) {
45 var plug = context[i];
46 if (plug.name == "DEFAULT") {
47 continue;
48 }
49 return plug;
50 }
51 return { styleIdentifier: function() { return null; } };
52 }
53
54 function addPluginPattern(pluginName, cmdStyle, styles) {
55 return function () {
56 this.name = pluginName;
57 this.bracketNo = 0;
58 this.style = cmdStyle;
59 this.styles = styles;
60 this.argument = null; // \begin and \end have arguments that follow. These are stored in the plugin
61
62 this.styleIdentifier = function() {
63 return this.styles[this.bracketNo - 1] || null;
64 };
65 this.openBracket = function() {
66 this.bracketNo++;
67 return "bracket";
68 };
69 this.closeBracket = function() {};
70 };
71 }
72
73 var plugins = {};
74
75 plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]);
76 plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]);
77 plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]);
78 plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]);
79 plugins["end"] = addPluginPattern("end", "tag", ["atom"]);
80
81 plugins["DEFAULT"] = function () {
82 this.name = "DEFAULT";
83 this.style = "tag";
84
85 this.styleIdentifier = this.openBracket = this.closeBracket = function() {};
86 };
87
88 function setState(state, f) {
89 state.f = f;
90 }
91
92 // called when in a normal (no environment) context
93 function normal(source, state) {
94 var plug;
95 // Do we look like '\command' ? If so, attempt to apply the plugin 'command'
96 if (source.match(/^\\[a-zA-Z@]+/)) {
97 var cmdName = source.current().slice(1);
98 plug = plugins[cmdName] || plugins["DEFAULT"];
99 plug = new plug();
100 pushCommand(state, plug);
101 setState(state, beginParams);
102 return plug.style;
103 }
104
105 // escape characters
106 if (source.match(/^\\[$&%#{}_]/)) {
107 return "tag";
108 }
109
110 // white space control characters
111 if (source.match(/^\\[,;!\/\\]/)) {
112 return "tag";
113 }
114
115 // find if we're starting various math modes
116 if (source.match("\\[")) {
117 setState(state, function(source, state){ return inMathMode(source, state, "\\]"); });
118 return "keyword";
119 }
120 if (source.match("$$")) {
121 setState(state, function(source, state){ return inMathMode(source, state, "$$"); });
122 return "keyword";
123 }
124 if (source.match("$")) {
125 setState(state, function(source, state){ return inMathMode(source, state, "$"); });
126 return "keyword";
127 }
128
129 var ch = source.next();
130 if (ch == "%") {
131 // special case: % at end of its own line; stay in same state
132 if (!source.eol()) {
133 setState(state, inCComment);
134 }
135 return "comment";
136 }
137 else if (ch == '}' || ch == ']') {
138 plug = peekCommand(state);
139 if (plug) {
140 plug.closeBracket(ch);
141 setState(state, beginParams);
142 } else {
143 return "error";
144 }
145 return "bracket";
146 } else if (ch == '{' || ch == '[') {
147 plug = plugins["DEFAULT"];
148 plug = new plug();
149 pushCommand(state, plug);
150 return "bracket";
151 }
152 else if (/\d/.test(ch)) {
153 source.eatWhile(/[\w.%]/);
154 return "atom";
155 }
156 else {
157 source.eatWhile(/[\w\-_]/);
158 plug = getMostPowerful(state);
159 if (plug.name == 'begin') {
160 plug.argument = source.current();
161 }
162 return plug.styleIdentifier();
163 }
164 }
165
166 function inCComment(source, state) {
167 source.skipToEnd();
168 setState(state, normal);
169 return "comment";
170 }
171
172 function inMathMode(source, state, endModeSeq) {
173 if (source.eatSpace()) {
174 return null;
175 }
176 if (source.match(endModeSeq)) {
177 setState(state, normal);
178 return "keyword";
179 }
180 if (source.match(/^\\[a-zA-Z@]+/)) {
181 return "tag";
182 }
183 if (source.match(/^[a-zA-Z]+/)) {
184 return "variable-2";
185 }
186 // escape characters
187 if (source.match(/^\\[$&%#{}_]/)) {
188 return "tag";
189 }
190 // white space control characters
191 if (source.match(/^\\[,;!\/]/)) {
192 return "tag";
193 }
194 // special math-mode characters
195 if (source.match(/^[\^_&]/)) {
196 return "tag";
197 }
198 // non-special characters
199 if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
200 return null;
201 }
202 if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
203 return "number";
204 }
205 var ch = source.next();
206 if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") {
207 return "bracket";
208 }
209
210 // eat comments here, because inCComment returns us to normal state!
211 if (ch == "%") {
212 if (!source.eol()) {
213 source.skipToEnd();
214 }
215 return "comment";
216 }
217 return "error";
218 }
219
220 function beginParams(source, state) {
221 var ch = source.peek(), lastPlug;
222 if (ch == '{' || ch == '[') {
223 lastPlug = peekCommand(state);
224 lastPlug.openBracket(ch);
225 source.eat(ch);
226 setState(state, normal);
227 return "bracket";
228 }
229 if (/[ \t\r]/.test(ch)) {
230 source.eat(ch);
231 return null;
232 }
233 setState(state, normal);
234 popCommand(state);
235
236 return normal(source, state);
237 }
238
239 return {
240 startState: function() {
241 return {
242 cmdState: [],
243 f: normal
244 };
245 },
246 copyState: function(s) {
247 return {
248 cmdState: s.cmdState.slice(),
249 f: s.f
250 };
251 },
252 token: function(stream, state) {
253 return state.f(stream, state);
254 },
255 lineComment: "%"
256 };
257 });
258
259 CodeMirror.defineMIME("text/x-stex", "stex");
260 CodeMirror.defineMIME("text/x-latex", "stex");
261
262 });
@@ -1,147 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 //tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMode("tcl", function() {
17 function parseWords(str) {
18 var obj = {}, words = str.split(" ");
19 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
20 return obj;
21 }
22 var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " +
23 "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " +
24 "binary break catch cd close concat continue dde eof encoding error " +
25 "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " +
26 "filename flush for foreach format gets glob global history http if " +
27 "incr info interp join lappend lindex linsert list llength load lrange " +
28 "lreplace lsearch lset lsort memory msgcat namespace open package parray " +
29 "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " +
30 "registry regsub rename resource return scan seek set socket source split " +
31 "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " +
32 "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " +
33 "tclvars tell time trace unknown unset update uplevel upvar variable " +
34 "vwait");
35 var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
36 var isOperatorChar = /[+\-*&%=<>!?^\/\|]/;
37 function chain(stream, state, f) {
38 state.tokenize = f;
39 return f(stream, state);
40 }
41 function tokenBase(stream, state) {
42 var beforeParams = state.beforeParams;
43 state.beforeParams = false;
44 var ch = stream.next();
45 if ((ch == '"' || ch == "'") && state.inParams)
46 return chain(stream, state, tokenString(ch));
47 else if (/[\[\]{}\(\),;\.]/.test(ch)) {
48 if (ch == "(" && beforeParams) state.inParams = true;
49 else if (ch == ")") state.inParams = false;
50 return null;
51 }
52 else if (/\d/.test(ch)) {
53 stream.eatWhile(/[\w\.]/);
54 return "number";
55 }
56 else if (ch == "#" && stream.eat("*")) {
57 return chain(stream, state, tokenComment);
58 }
59 else if (ch == "#" && stream.match(/ *\[ *\[/)) {
60 return chain(stream, state, tokenUnparsed);
61 }
62 else if (ch == "#" && stream.eat("#")) {
63 stream.skipToEnd();
64 return "comment";
65 }
66 else if (ch == '"') {
67 stream.skipTo(/"/);
68 return "comment";
69 }
70 else if (ch == "$") {
71 stream.eatWhile(/[$_a-z0-9A-Z\.{:]/);
72 stream.eatWhile(/}/);
73 state.beforeParams = true;
74 return "builtin";
75 }
76 else if (isOperatorChar.test(ch)) {
77 stream.eatWhile(isOperatorChar);
78 return "comment";
79 }
80 else {
81 stream.eatWhile(/[\w\$_{}\xa1-\uffff]/);
82 var word = stream.current().toLowerCase();
83 if (keywords && keywords.propertyIsEnumerable(word))
84 return "keyword";
85 if (functions && functions.propertyIsEnumerable(word)) {
86 state.beforeParams = true;
87 return "keyword";
88 }
89 return null;
90 }
91 }
92 function tokenString(quote) {
93 return function(stream, state) {
94 var escaped = false, next, end = false;
95 while ((next = stream.next()) != null) {
96 if (next == quote && !escaped) {
97 end = true;
98 break;
99 }
100 escaped = !escaped && next == "\\";
101 }
102 if (end) state.tokenize = tokenBase;
103 return "string";
104 };
105 }
106 function tokenComment(stream, state) {
107 var maybeEnd = false, ch;
108 while (ch = stream.next()) {
109 if (ch == "#" && maybeEnd) {
110 state.tokenize = tokenBase;
111 break;
112 }
113 maybeEnd = (ch == "*");
114 }
115 return "comment";
116 }
117 function tokenUnparsed(stream, state) {
118 var maybeEnd = 0, ch;
119 while (ch = stream.next()) {
120 if (ch == "#" && maybeEnd == 2) {
121 state.tokenize = tokenBase;
122 break;
123 }
124 if (ch == "]")
125 maybeEnd++;
126 else if (ch != " ")
127 maybeEnd = 0;
128 }
129 return "meta";
130 }
131 return {
132 startState: function() {
133 return {
134 tokenize: tokenBase,
135 beforeParams: false,
136 inParams: false
137 };
138 },
139 token: function(stream, state) {
140 if (stream.eatSpace()) return null;
141 return state.tokenize(stream, state);
142 }
143 };
144 });
145 CodeMirror.defineMIME("text/x-tcl", "tcl");
146
147 });
This diff has been collapsed as it changes many lines, (553 lines changed) Show them Hide them
@@ -1,553 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == 'object' && typeof module == 'object') { // CommonJS
6 mod(require('../../lib/codemirror'));
7 } else if (typeof define == 'function' && define.amd) { // AMD
8 define(['../../lib/codemirror'], mod);
9 } else { // Plain browser env
10 mod(CodeMirror);
11 }
12 })(function(CodeMirror) {
13 'use strict';
14
15 var TOKEN_STYLES = {
16 addition: 'positive',
17 attributes: 'attribute',
18 bold: 'strong',
19 cite: 'keyword',
20 code: 'atom',
21 definitionList: 'number',
22 deletion: 'negative',
23 div: 'punctuation',
24 em: 'em',
25 footnote: 'variable',
26 footCite: 'qualifier',
27 header: 'header',
28 html: 'comment',
29 image: 'string',
30 italic: 'em',
31 link: 'link',
32 linkDefinition: 'link',
33 list1: 'variable-2',
34 list2: 'variable-3',
35 list3: 'keyword',
36 notextile: 'string-2',
37 pre: 'operator',
38 p: 'property',
39 quote: 'bracket',
40 span: 'quote',
41 specialChar: 'tag',
42 strong: 'strong',
43 sub: 'builtin',
44 sup: 'builtin',
45 table: 'variable-3',
46 tableHeading: 'operator'
47 };
48
49 function Parser(regExpFactory, state, stream) {
50 this.regExpFactory = regExpFactory;
51 this.state = state;
52 this.stream = stream;
53 this.styles = TOKEN_STYLES;
54
55 this.state.specialChar = null;
56 }
57
58 Parser.prototype.eat = function(name) {
59 return this.stream.match(this.regExpFactory.pattern(name), true);
60 };
61
62 Parser.prototype.check = function(name) {
63 return this.stream.match(this.regExpFactory.pattern(name), false);
64 };
65
66 Parser.prototype.setModeForNextToken = function(mode) {
67 return this.state.mode = mode;
68 };
69
70 Parser.prototype.execMode = function(newMode) {
71 return this.setModeForNextToken(newMode).call(this);
72 };
73
74 Parser.prototype.startNewLine = function() {
75 this.setModeForNextToken(Modes.newLayout);
76 this.state.tableHeading = false;
77
78 if (this.state.layoutType === 'definitionList' && this.state.spanningLayout) {
79 if (this.check('definitionListEnd')) {
80 this.state.spanningLayout = false;
81 }
82 }
83 };
84
85 Parser.prototype.nextToken = function() {
86 return this.state.mode.call(this);
87 };
88
89 Parser.prototype.styleFor = function(token) {
90 if (this.styles.hasOwnProperty(token)) {
91 return this.styles[token];
92 }
93 throw 'unknown token';
94 };
95
96 Parser.prototype.handlePhraseModifier = function(ch) {
97 if (ch === '_') {
98 if (this.stream.eat('_')) {
99 return this.togglePhraseModifier('italic', /^.*__/);
100 }
101 return this.togglePhraseModifier('em', /^.*_/);
102 }
103
104 if (ch === '*') {
105 if (this.stream.eat('*')) {
106 return this.togglePhraseModifier('bold', /^.*\*\*/);
107 }
108 return this.togglePhraseModifier('strong', /^.*\*/);
109 }
110
111 if (ch === '[') {
112 if (this.stream.match(/\d+\]/)) {
113 this.state.footCite = true;
114 }
115 return this.tokenStyles();
116 }
117
118 if (ch === '(') {
119 if (this.stream.match('r)')) {
120 this.state.specialChar = 'r';
121 } else if (this.stream.match('tm)')) {
122 this.state.specialChar = 'tm';
123 } else if (this.stream.match('c)')) {
124 this.state.specialChar = 'c';
125 }
126 return this.tokenStyles();
127 }
128
129 if (ch === '<') {
130 if (this.stream.match(/(\w+)[^>]+>[^<]+<\/\1>/)) {
131 return this.tokenStylesWith(this.styleFor('html'));
132 }
133 }
134
135 if (ch === '?' && this.stream.eat('?')) {
136 return this.togglePhraseModifier('cite', /^.*\?\?/);
137 }
138 if (ch === '=' && this.stream.eat('=')) {
139 return this.togglePhraseModifier('notextile', /^.*==/);
140 }
141 if (ch === '-') {
142 return this.togglePhraseModifier('deletion', /^.*-/);
143 }
144 if (ch === '+') {
145 return this.togglePhraseModifier('addition', /^.*\+/);
146 }
147 if (ch === '~') {
148 return this.togglePhraseModifier('sub', /^.*~/);
149 }
150 if (ch === '^') {
151 return this.togglePhraseModifier('sup', /^.*\^/);
152 }
153 if (ch === '%') {
154 return this.togglePhraseModifier('span', /^.*%/);
155 }
156 if (ch === '@') {
157 return this.togglePhraseModifier('code', /^.*@/);
158 }
159 if (ch === '!') {
160 var type = this.togglePhraseModifier('image', /^.*(?:\([^\)]+\))?!/);
161 this.stream.match(/^:\S+/); // optional Url portion
162 return type;
163 }
164 return this.tokenStyles();
165 };
166
167 Parser.prototype.togglePhraseModifier = function(phraseModifier, closeRE) {
168 if (this.state[phraseModifier]) { // remove phrase modifier
169 var type = this.tokenStyles();
170 this.state[phraseModifier] = false;
171 return type;
172 }
173 if (this.stream.match(closeRE, false)) { // add phrase modifier
174 this.state[phraseModifier] = true;
175 this.setModeForNextToken(Modes.attributes);
176 }
177 return this.tokenStyles();
178 };
179
180 Parser.prototype.tokenStyles = function() {
181 var disabled = this.textileDisabled(),
182 styles = [];
183
184 if (disabled) return disabled;
185
186 if (this.state.layoutType) {
187 styles.push(this.styleFor(this.state.layoutType));
188 }
189
190 styles = styles.concat(this.activeStyles('addition', 'bold', 'cite', 'code',
191 'deletion', 'em', 'footCite', 'image', 'italic', 'link', 'span', 'specialChar', 'strong',
192 'sub', 'sup', 'table', 'tableHeading'));
193
194 if (this.state.layoutType === 'header') {
195 styles.push(this.styleFor('header') + '-' + this.state.header);
196 }
197 return styles.length ? styles.join(' ') : null;
198 };
199
200 Parser.prototype.textileDisabled = function() {
201 var type = this.state.layoutType;
202
203 switch(type) {
204 case 'notextile':
205 case 'code':
206 case 'pre':
207 return this.styleFor(type);
208 default:
209 if (this.state.notextile) {
210 return this.styleFor('notextile') + (type ? (' ' + this.styleFor(type)) : '');
211 }
212
213 return null;
214 }
215 };
216
217 Parser.prototype.tokenStylesWith = function(extraStyles) {
218 var disabled = this.textileDisabled(),
219 type;
220
221 if (disabled) return disabled;
222
223 type = this.tokenStyles();
224 if(extraStyles) {
225 return type ? (type + ' ' + extraStyles) : extraStyles;
226 }
227 return type;
228 };
229
230 Parser.prototype.activeStyles = function() {
231 var styles = [],
232 i;
233 for (i = 0; i < arguments.length; ++i) {
234 if (this.state[arguments[i]]) {
235 styles.push(this.styleFor(arguments[i]));
236 }
237 }
238 return styles;
239 };
240
241 Parser.prototype.blankLine = function() {
242 var spanningLayout = this.state.spanningLayout,
243 type = this.state.layoutType,
244 key;
245
246 for (key in this.state) {
247 if (this.state.hasOwnProperty(key)) {
248 delete this.state[key];
249 }
250 }
251
252 this.setModeForNextToken(Modes.newLayout);
253 if (spanningLayout) {
254 this.state.layoutType = type;
255 this.state.spanningLayout = true;
256 }
257 };
258
259
260 function RegExpFactory() {
261 this.cache = {};
262 this.single = {
263 bc: 'bc',
264 bq: 'bq',
265 definitionList: /- [^(?::=)]+:=+/,
266 definitionListEnd: /.*=:\s*$/,
267 div: 'div',
268 drawTable: /\|.*\|/,
269 foot: /fn\d+/,
270 header: /h[1-6]/,
271 html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/,
272 link: /[^"]+":\S/,
273 linkDefinition: /\[[^\s\]]+\]\S+/,
274 list: /(?:#+|\*+)/,
275 notextile: 'notextile',
276 para: 'p',
277 pre: 'pre',
278 table: 'table',
279 tableCellAttributes: /[/\\]\d+/,
280 tableHeading: /\|_\./,
281 tableText: /[^"_\*\[\(\?\+~\^%@|-]+/,
282 text: /[^!"_=\*\[\(<\?\+~\^%@-]+/
283 };
284 this.attributes = {
285 align: /(?:<>|<|>|=)/,
286 selector: /\([^\(][^\)]+\)/,
287 lang: /\[[^\[\]]+\]/,
288 pad: /(?:\(+|\)+){1,2}/,
289 css: /\{[^\}]+\}/
290 };
291 }
292
293 RegExpFactory.prototype.pattern = function(name) {
294 return (this.cache[name] || this.createRe(name));
295 };
296
297 RegExpFactory.prototype.createRe = function(name) {
298 switch (name) {
299 case 'drawTable':
300 return this.makeRe('^', this.single.drawTable, '$');
301 case 'html':
302 return this.makeRe('^', this.single.html, '(?:', this.single.html, ')*', '$');
303 case 'linkDefinition':
304 return this.makeRe('^', this.single.linkDefinition, '$');
305 case 'listLayout':
306 return this.makeRe('^', this.single.list, this.pattern('allAttributes'), '*\\s+');
307 case 'tableCellAttributes':
308 return this.makeRe('^', this.choiceRe(this.single.tableCellAttributes,
309 this.pattern('allAttributes')), '+\\.');
310 case 'type':
311 return this.makeRe('^', this.pattern('allTypes'));
312 case 'typeLayout':
313 return this.makeRe('^', this.pattern('allTypes'), this.pattern('allAttributes'),
314 '*\\.\\.?', '(\\s+|$)');
315 case 'attributes':
316 return this.makeRe('^', this.pattern('allAttributes'), '+');
317
318 case 'allTypes':
319 return this.choiceRe(this.single.div, this.single.foot,
320 this.single.header, this.single.bc, this.single.bq,
321 this.single.notextile, this.single.pre, this.single.table,
322 this.single.para);
323
324 case 'allAttributes':
325 return this.choiceRe(this.attributes.selector, this.attributes.css,
326 this.attributes.lang, this.attributes.align, this.attributes.pad);
327
328 default:
329 return this.makeRe('^', this.single[name]);
330 }
331 };
332
333
334 RegExpFactory.prototype.makeRe = function() {
335 var pattern = '',
336 i,
337 arg;
338
339 for (i = 0; i < arguments.length; ++i) {
340 arg = arguments[i];
341 pattern += (typeof arg === 'string') ? arg : arg.source;
342 }
343 return new RegExp(pattern);
344 };
345
346 RegExpFactory.prototype.choiceRe = function() {
347 var parts = [arguments[0]],
348 i;
349
350 for (i = 1; i < arguments.length; ++i) {
351 parts[i * 2 - 1] = '|';
352 parts[i * 2] = arguments[i];
353 }
354
355 parts.unshift('(?:');
356 parts.push(')');
357 return this.makeRe.apply(this, parts);
358 };
359
360
361 var Modes = {
362 newLayout: function() {
363 if (this.check('typeLayout')) {
364 this.state.spanningLayout = false;
365 return this.execMode(Modes.blockType);
366 }
367 if (!this.textileDisabled()) {
368 if (this.check('listLayout')) {
369 return this.execMode(Modes.list);
370 } else if (this.check('drawTable')) {
371 return this.execMode(Modes.table);
372 } else if (this.check('linkDefinition')) {
373 return this.execMode(Modes.linkDefinition);
374 } else if (this.check('definitionList')) {
375 return this.execMode(Modes.definitionList);
376 } else if (this.check('html')) {
377 return this.execMode(Modes.html);
378 }
379 }
380 return this.execMode(Modes.text);
381 },
382
383 blockType: function() {
384 var match,
385 type;
386 this.state.layoutType = null;
387
388 if (match = this.eat('type')) {
389 type = match[0];
390 } else {
391 return this.execMode(Modes.text);
392 }
393
394 if(match = type.match(this.regExpFactory.pattern('header'))) {
395 this.state.layoutType = 'header';
396 this.state.header = parseInt(match[0][1]);
397 } else if (type.match(this.regExpFactory.pattern('bq'))) {
398 this.state.layoutType = 'quote';
399 } else if (type.match(this.regExpFactory.pattern('bc'))) {
400 this.state.layoutType = 'code';
401 } else if (type.match(this.regExpFactory.pattern('foot'))) {
402 this.state.layoutType = 'footnote';
403 } else if (type.match(this.regExpFactory.pattern('notextile'))) {
404 this.state.layoutType = 'notextile';
405 } else if (type.match(this.regExpFactory.pattern('pre'))) {
406 this.state.layoutType = 'pre';
407 } else if (type.match(this.regExpFactory.pattern('div'))) {
408 this.state.layoutType = 'div';
409 } else if (type.match(this.regExpFactory.pattern('table'))) {
410 this.state.layoutType = 'table';
411 }
412
413 this.setModeForNextToken(Modes.attributes);
414 return this.tokenStyles();
415 },
416
417 text: function() {
418 if (this.eat('text')) {
419 return this.tokenStyles();
420 }
421
422 var ch = this.stream.next();
423
424 if (ch === '"') {
425 return this.execMode(Modes.link);
426 }
427 return this.handlePhraseModifier(ch);
428 },
429
430 attributes: function() {
431 this.setModeForNextToken(Modes.layoutLength);
432
433 if (this.eat('attributes')) {
434 return this.tokenStylesWith(this.styleFor('attributes'));
435 }
436 return this.tokenStyles();
437 },
438
439 layoutLength: function() {
440 if (this.stream.eat('.') && this.stream.eat('.')) {
441 this.state.spanningLayout = true;
442 }
443
444 this.setModeForNextToken(Modes.text);
445 return this.tokenStyles();
446 },
447
448 list: function() {
449 var match = this.eat('list'),
450 listMod;
451 this.state.listDepth = match[0].length;
452 listMod = (this.state.listDepth - 1) % 3;
453 if (!listMod) {
454 this.state.layoutType = 'list1';
455 } else if (listMod === 1) {
456 this.state.layoutType = 'list2';
457 } else {
458 this.state.layoutType = 'list3';
459 }
460 this.setModeForNextToken(Modes.attributes);
461 return this.tokenStyles();
462 },
463
464 link: function() {
465 this.setModeForNextToken(Modes.text);
466 if (this.eat('link')) {
467 this.stream.match(/\S+/);
468 return this.tokenStylesWith(this.styleFor('link'));
469 }
470 return this.tokenStyles();
471 },
472
473 linkDefinition: function() {
474 this.stream.skipToEnd();
475 return this.tokenStylesWith(this.styleFor('linkDefinition'));
476 },
477
478 definitionList: function() {
479 this.eat('definitionList');
480
481 this.state.layoutType = 'definitionList';
482
483 if (this.stream.match(/\s*$/)) {
484 this.state.spanningLayout = true;
485 } else {
486 this.setModeForNextToken(Modes.attributes);
487 }
488 return this.tokenStyles();
489 },
490
491 html: function() {
492 this.stream.skipToEnd();
493 return this.tokenStylesWith(this.styleFor('html'));
494 },
495
496 table: function() {
497 this.state.layoutType = 'table';
498 return this.execMode(Modes.tableCell);
499 },
500
501 tableCell: function() {
502 if (this.eat('tableHeading')) {
503 this.state.tableHeading = true;
504 } else {
505 this.stream.eat('|');
506 }
507 this.setModeForNextToken(Modes.tableCellAttributes);
508 return this.tokenStyles();
509 },
510
511 tableCellAttributes: function() {
512 this.setModeForNextToken(Modes.tableText);
513
514 if (this.eat('tableCellAttributes')) {
515 return this.tokenStylesWith(this.styleFor('attributes'));
516 }
517 return this.tokenStyles();
518 },
519
520 tableText: function() {
521 if (this.eat('tableText')) {
522 return this.tokenStyles();
523 }
524
525 if (this.stream.peek() === '|') { // end of cell
526 this.setModeForNextToken(Modes.tableCell);
527 return this.tokenStyles();
528 }
529 return this.handlePhraseModifier(this.stream.next());
530 }
531 };
532
533
534 CodeMirror.defineMode('textile', function() {
535 var regExpFactory = new RegExpFactory();
536
537 return {
538 startState: function() {
539 return { mode: Modes.newLayout };
540 },
541 token: function(stream, state) {
542 var parser = new Parser(regExpFactory, state, stream);
543 if (stream.sol()) { parser.startNewLine(); }
544 return parser.nextToken();
545 },
546 blankLine: function(state) {
547 new Parser(regExpFactory, state).blankLine();
548 }
549 };
550 });
551
552 CodeMirror.defineMIME('text/x-textile', 'textile');
553 });
@@ -1,14 +0,0 b''
1 span.cm-underlined {
2 text-decoration: underline;
3 }
4 span.cm-strikethrough {
5 text-decoration: line-through;
6 }
7 span.cm-brace {
8 color: #170;
9 font-weight: bold;
10 }
11 span.cm-table {
12 color: blue;
13 font-weight: bold;
14 }
@@ -1,369 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /***
5 |''Name''|tiddlywiki.js|
6 |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror|
7 |''Author''|PMario|
8 |''Version''|0.1.7|
9 |''Status''|''stable''|
10 |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
11 |''Documentation''|http://codemirror.tiddlyspace.com/|
12 |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
13 |''CoreVersion''|2.5.0|
14 |''Requires''|codemirror.js|
15 |''Keywords''|syntax highlighting color code mirror codemirror|
16 ! Info
17 CoreVersion parameter is needed for TiddlyWiki only!
18 ***/
19 //{{{
20
21 (function(mod) {
22 if (typeof exports == "object" && typeof module == "object") // CommonJS
23 mod(require("../../lib/codemirror"));
24 else if (typeof define == "function" && define.amd) // AMD
25 define(["../../lib/codemirror"], mod);
26 else // Plain browser env
27 mod(CodeMirror);
28 })(function(CodeMirror) {
29 "use strict";
30
31 CodeMirror.defineMode("tiddlywiki", function () {
32 // Tokenizer
33 var textwords = {};
34
35 var keywords = function () {
36 function kw(type) {
37 return { type: type, style: "macro"};
38 }
39 return {
40 "allTags": kw('allTags'), "closeAll": kw('closeAll'), "list": kw('list'),
41 "newJournal": kw('newJournal'), "newTiddler": kw('newTiddler'),
42 "permaview": kw('permaview'), "saveChanges": kw('saveChanges'),
43 "search": kw('search'), "slider": kw('slider'), "tabs": kw('tabs'),
44 "tag": kw('tag'), "tagging": kw('tagging'), "tags": kw('tags'),
45 "tiddler": kw('tiddler'), "timeline": kw('timeline'),
46 "today": kw('today'), "version": kw('version'), "option": kw('option'),
47
48 "with": kw('with'),
49 "filter": kw('filter')
50 };
51 }();
52
53 var isSpaceName = /[\w_\-]/i,
54 reHR = /^\-\-\-\-+$/, // <hr>
55 reWikiCommentStart = /^\/\*\*\*$/, // /***
56 reWikiCommentStop = /^\*\*\*\/$/, // ***/
57 reBlockQuote = /^<<<$/,
58
59 reJsCodeStart = /^\/\/\{\{\{$/, // //{{{ js block start
60 reJsCodeStop = /^\/\/\}\}\}$/, // //}}} js stop
61 reXmlCodeStart = /^<!--\{\{\{-->$/, // xml block start
62 reXmlCodeStop = /^<!--\}\}\}-->$/, // xml stop
63
64 reCodeBlockStart = /^\{\{\{$/, // {{{ TW text div block start
65 reCodeBlockStop = /^\}\}\}$/, // }}} TW text stop
66
67 reUntilCodeStop = /.*?\}\}\}/;
68
69 function chain(stream, state, f) {
70 state.tokenize = f;
71 return f(stream, state);
72 }
73
74 // Used as scratch variables to communicate multiple values without
75 // consing up tons of objects.
76 var type, content;
77
78 function ret(tp, style, cont) {
79 type = tp;
80 content = cont;
81 return style;
82 }
83
84 function jsTokenBase(stream, state) {
85 var sol = stream.sol(), ch;
86
87 state.block = false; // indicates the start of a code block.
88
89 ch = stream.peek(); // don't eat, to make matching simpler
90
91 // check start of blocks
92 if (sol && /[<\/\*{}\-]/.test(ch)) {
93 if (stream.match(reCodeBlockStart)) {
94 state.block = true;
95 return chain(stream, state, twTokenCode);
96 }
97 if (stream.match(reBlockQuote)) {
98 return ret('quote', 'quote');
99 }
100 if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop)) {
101 return ret('code', 'comment');
102 }
103 if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop)) {
104 return ret('code', 'comment');
105 }
106 if (stream.match(reHR)) {
107 return ret('hr', 'hr');
108 }
109 } // sol
110 ch = stream.next();
111
112 if (sol && /[\/\*!#;:>|]/.test(ch)) {
113 if (ch == "!") { // tw header
114 stream.skipToEnd();
115 return ret("header", "header");
116 }
117 if (ch == "*") { // tw list
118 stream.eatWhile('*');
119 return ret("list", "comment");
120 }
121 if (ch == "#") { // tw numbered list
122 stream.eatWhile('#');
123 return ret("list", "comment");
124 }
125 if (ch == ";") { // definition list, term
126 stream.eatWhile(';');
127 return ret("list", "comment");
128 }
129 if (ch == ":") { // definition list, description
130 stream.eatWhile(':');
131 return ret("list", "comment");
132 }
133 if (ch == ">") { // single line quote
134 stream.eatWhile(">");
135 return ret("quote", "quote");
136 }
137 if (ch == '|') {
138 return ret('table', 'header');
139 }
140 }
141
142 if (ch == '{' && stream.match(/\{\{/)) {
143 return chain(stream, state, twTokenCode);
144 }
145
146 // rudimentary html:// file:// link matching. TW knows much more ...
147 if (/[hf]/i.test(ch)) {
148 if (/[ti]/i.test(stream.peek()) && stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i)) {
149 return ret("link", "link");
150 }
151 }
152 // just a little string indicator, don't want to have the whole string covered
153 if (ch == '"') {
154 return ret('string', 'string');
155 }
156 if (ch == '~') { // _no_ CamelCase indicator should be bold
157 return ret('text', 'brace');
158 }
159 if (/[\[\]]/.test(ch)) { // check for [[..]]
160 if (stream.peek() == ch) {
161 stream.next();
162 return ret('brace', 'brace');
163 }
164 }
165 if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting
166 stream.eatWhile(isSpaceName);
167 return ret("link", "link");
168 }
169 if (/\d/.test(ch)) { // numbers
170 stream.eatWhile(/\d/);
171 return ret("number", "number");
172 }
173 if (ch == "/") { // tw invisible comment
174 if (stream.eat("%")) {
175 return chain(stream, state, twTokenComment);
176 }
177 else if (stream.eat("/")) { //
178 return chain(stream, state, twTokenEm);
179 }
180 }
181 if (ch == "_") { // tw underline
182 if (stream.eat("_")) {
183 return chain(stream, state, twTokenUnderline);
184 }
185 }
186 // strikethrough and mdash handling
187 if (ch == "-") {
188 if (stream.eat("-")) {
189 // if strikethrough looks ugly, change CSS.
190 if (stream.peek() != ' ')
191 return chain(stream, state, twTokenStrike);
192 // mdash
193 if (stream.peek() == ' ')
194 return ret('text', 'brace');
195 }
196 }
197 if (ch == "'") { // tw bold
198 if (stream.eat("'")) {
199 return chain(stream, state, twTokenStrong);
200 }
201 }
202 if (ch == "<") { // tw macro
203 if (stream.eat("<")) {
204 return chain(stream, state, twTokenMacro);
205 }
206 }
207 else {
208 return ret(ch);
209 }
210
211 // core macro handling
212 stream.eatWhile(/[\w\$_]/);
213 var word = stream.current(),
214 known = textwords.propertyIsEnumerable(word) && textwords[word];
215
216 return known ? ret(known.type, known.style, word) : ret("text", null, word);
217
218 } // jsTokenBase()
219
220 // tw invisible comment
221 function twTokenComment(stream, state) {
222 var maybeEnd = false,
223 ch;
224 while (ch = stream.next()) {
225 if (ch == "/" && maybeEnd) {
226 state.tokenize = jsTokenBase;
227 break;
228 }
229 maybeEnd = (ch == "%");
230 }
231 return ret("comment", "comment");
232 }
233
234 // tw strong / bold
235 function twTokenStrong(stream, state) {
236 var maybeEnd = false,
237 ch;
238 while (ch = stream.next()) {
239 if (ch == "'" && maybeEnd) {
240 state.tokenize = jsTokenBase;
241 break;
242 }
243 maybeEnd = (ch == "'");
244 }
245 return ret("text", "strong");
246 }
247
248 // tw code
249 function twTokenCode(stream, state) {
250 var ch, sb = state.block;
251
252 if (sb && stream.current()) {
253 return ret("code", "comment");
254 }
255
256 if (!sb && stream.match(reUntilCodeStop)) {
257 state.tokenize = jsTokenBase;
258 return ret("code", "comment");
259 }
260
261 if (sb && stream.sol() && stream.match(reCodeBlockStop)) {
262 state.tokenize = jsTokenBase;
263 return ret("code", "comment");
264 }
265
266 ch = stream.next();
267 return (sb) ? ret("code", "comment") : ret("code", "comment");
268 }
269
270 // tw em / italic
271 function twTokenEm(stream, state) {
272 var maybeEnd = false,
273 ch;
274 while (ch = stream.next()) {
275 if (ch == "/" && maybeEnd) {
276 state.tokenize = jsTokenBase;
277 break;
278 }
279 maybeEnd = (ch == "/");
280 }
281 return ret("text", "em");
282 }
283
284 // tw underlined text
285 function twTokenUnderline(stream, state) {
286 var maybeEnd = false,
287 ch;
288 while (ch = stream.next()) {
289 if (ch == "_" && maybeEnd) {
290 state.tokenize = jsTokenBase;
291 break;
292 }
293 maybeEnd = (ch == "_");
294 }
295 return ret("text", "underlined");
296 }
297
298 // tw strike through text looks ugly
299 // change CSS if needed
300 function twTokenStrike(stream, state) {
301 var maybeEnd = false, ch;
302
303 while (ch = stream.next()) {
304 if (ch == "-" && maybeEnd) {
305 state.tokenize = jsTokenBase;
306 break;
307 }
308 maybeEnd = (ch == "-");
309 }
310 return ret("text", "strikethrough");
311 }
312
313 // macro
314 function twTokenMacro(stream, state) {
315 var ch, word, known;
316
317 if (stream.current() == '<<') {
318 return ret('brace', 'macro');
319 }
320
321 ch = stream.next();
322 if (!ch) {
323 state.tokenize = jsTokenBase;
324 return ret(ch);
325 }
326 if (ch == ">") {
327 if (stream.peek() == '>') {
328 stream.next();
329 state.tokenize = jsTokenBase;
330 return ret("brace", "macro");
331 }
332 }
333
334 stream.eatWhile(/[\w\$_]/);
335 word = stream.current();
336 known = keywords.propertyIsEnumerable(word) && keywords[word];
337
338 if (known) {
339 return ret(known.type, known.style, word);
340 }
341 else {
342 return ret("macro", null, word);
343 }
344 }
345
346 // Interface
347 return {
348 startState: function () {
349 return {
350 tokenize: jsTokenBase,
351 indented: 0,
352 level: 0
353 };
354 },
355
356 token: function (stream, state) {
357 if (stream.eatSpace()) return null;
358 var style = state.tokenize(stream, state);
359 return style;
360 },
361
362 electricChars: ""
363 };
364 });
365
366 CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki");
367 });
368
369 //}}}
@@ -1,26 +0,0 b''
1 .cm-tw-syntaxerror {
2 color: #FFF;
3 background-color: #900;
4 }
5
6 .cm-tw-deleted {
7 text-decoration: line-through;
8 }
9
10 .cm-tw-header5 {
11 font-weight: bold;
12 }
13 .cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/
14 padding-left: 10px;
15 }
16
17 .cm-tw-box {
18 border-top-width: 0px ! important;
19 border-style: solid;
20 border-width: 1px;
21 border-color: inherit;
22 }
23
24 .cm-tw-underline {
25 text-decoration: underline;
26 } No newline at end of file
@@ -1,323 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('tiki', function(config) {
15 function inBlock(style, terminator, returnTokenizer) {
16 return function(stream, state) {
17 while (!stream.eol()) {
18 if (stream.match(terminator)) {
19 state.tokenize = inText;
20 break;
21 }
22 stream.next();
23 }
24
25 if (returnTokenizer) state.tokenize = returnTokenizer;
26
27 return style;
28 };
29 }
30
31 function inLine(style) {
32 return function(stream, state) {
33 while(!stream.eol()) {
34 stream.next();
35 }
36 state.tokenize = inText;
37 return style;
38 };
39 }
40
41 function inText(stream, state) {
42 function chain(parser) {
43 state.tokenize = parser;
44 return parser(stream, state);
45 }
46
47 var sol = stream.sol();
48 var ch = stream.next();
49
50 //non start of line
51 switch (ch) { //switch is generally much faster than if, so it is used here
52 case "{": //plugin
53 stream.eat("/");
54 stream.eatSpace();
55 var tagName = "";
56 var c;
57 while ((c = stream.eat(/[^\s\u00a0=\"\'\/?(}]/))) tagName += c;
58 state.tokenize = inPlugin;
59 return "tag";
60 break;
61 case "_": //bold
62 if (stream.eat("_")) {
63 return chain(inBlock("strong", "__", inText));
64 }
65 break;
66 case "'": //italics
67 if (stream.eat("'")) {
68 // Italic text
69 return chain(inBlock("em", "''", inText));
70 }
71 break;
72 case "(":// Wiki Link
73 if (stream.eat("(")) {
74 return chain(inBlock("variable-2", "))", inText));
75 }
76 break;
77 case "[":// Weblink
78 return chain(inBlock("variable-3", "]", inText));
79 break;
80 case "|": //table
81 if (stream.eat("|")) {
82 return chain(inBlock("comment", "||"));
83 }
84 break;
85 case "-":
86 if (stream.eat("=")) {//titleBar
87 return chain(inBlock("header string", "=-", inText));
88 } else if (stream.eat("-")) {//deleted
89 return chain(inBlock("error tw-deleted", "--", inText));
90 }
91 break;
92 case "=": //underline
93 if (stream.match("==")) {
94 return chain(inBlock("tw-underline", "===", inText));
95 }
96 break;
97 case ":":
98 if (stream.eat(":")) {
99 return chain(inBlock("comment", "::"));
100 }
101 break;
102 case "^": //box
103 return chain(inBlock("tw-box", "^"));
104 break;
105 case "~": //np
106 if (stream.match("np~")) {
107 return chain(inBlock("meta", "~/np~"));
108 }
109 break;
110 }
111
112 //start of line types
113 if (sol) {
114 switch (ch) {
115 case "!": //header at start of line
116 if (stream.match('!!!!!')) {
117 return chain(inLine("header string"));
118 } else if (stream.match('!!!!')) {
119 return chain(inLine("header string"));
120 } else if (stream.match('!!!')) {
121 return chain(inLine("header string"));
122 } else if (stream.match('!!')) {
123 return chain(inLine("header string"));
124 } else {
125 return chain(inLine("header string"));
126 }
127 break;
128 case "*": //unordered list line item, or <li /> at start of line
129 case "#": //ordered list line item, or <li /> at start of line
130 case "+": //ordered list line item, or <li /> at start of line
131 return chain(inLine("tw-listitem bracket"));
132 break;
133 }
134 }
135
136 //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki
137 return null;
138 }
139
140 var indentUnit = config.indentUnit;
141
142 // Return variables for tokenizers
143 var pluginName, type;
144 function inPlugin(stream, state) {
145 var ch = stream.next();
146 var peek = stream.peek();
147
148 if (ch == "}") {
149 state.tokenize = inText;
150 //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin
151 return "tag";
152 } else if (ch == "(" || ch == ")") {
153 return "bracket";
154 } else if (ch == "=") {
155 type = "equals";
156
157 if (peek == ">") {
158 ch = stream.next();
159 peek = stream.peek();
160 }
161
162 //here we detect values directly after equal character with no quotes
163 if (!/[\'\"]/.test(peek)) {
164 state.tokenize = inAttributeNoQuote();
165 }
166 //end detect values
167
168 return "operator";
169 } else if (/[\'\"]/.test(ch)) {
170 state.tokenize = inAttribute(ch);
171 return state.tokenize(stream, state);
172 } else {
173 stream.eatWhile(/[^\s\u00a0=\"\'\/?]/);
174 return "keyword";
175 }
176 }
177
178 function inAttribute(quote) {
179 return function(stream, state) {
180 while (!stream.eol()) {
181 if (stream.next() == quote) {
182 state.tokenize = inPlugin;
183 break;
184 }
185 }
186 return "string";
187 };
188 }
189
190 function inAttributeNoQuote() {
191 return function(stream, state) {
192 while (!stream.eol()) {
193 var ch = stream.next();
194 var peek = stream.peek();
195 if (ch == " " || ch == "," || /[ )}]/.test(peek)) {
196 state.tokenize = inPlugin;
197 break;
198 }
199 }
200 return "string";
201 };
202 }
203
204 var curState, setStyle;
205 function pass() {
206 for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
207 }
208
209 function cont() {
210 pass.apply(null, arguments);
211 return true;
212 }
213
214 function pushContext(pluginName, startOfLine) {
215 var noIndent = curState.context && curState.context.noIndent;
216 curState.context = {
217 prev: curState.context,
218 pluginName: pluginName,
219 indent: curState.indented,
220 startOfLine: startOfLine,
221 noIndent: noIndent
222 };
223 }
224
225 function popContext() {
226 if (curState.context) curState.context = curState.context.prev;
227 }
228
229 function element(type) {
230 if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));}
231 else if (type == "closePlugin") {
232 var err = false;
233 if (curState.context) {
234 err = curState.context.pluginName != pluginName;
235 popContext();
236 } else {
237 err = true;
238 }
239 if (err) setStyle = "error";
240 return cont(endcloseplugin(err));
241 }
242 else if (type == "string") {
243 if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
244 if (curState.tokenize == inText) popContext();
245 return cont();
246 }
247 else return cont();
248 }
249
250 function endplugin(startOfLine) {
251 return function(type) {
252 if (
253 type == "selfclosePlugin" ||
254 type == "endPlugin"
255 )
256 return cont();
257 if (type == "endPlugin") {pushContext(curState.pluginName, startOfLine); return cont();}
258 return cont();
259 };
260 }
261
262 function endcloseplugin(err) {
263 return function(type) {
264 if (err) setStyle = "error";
265 if (type == "endPlugin") return cont();
266 return pass();
267 };
268 }
269
270 function attributes(type) {
271 if (type == "keyword") {setStyle = "attribute"; return cont(attributes);}
272 if (type == "equals") return cont(attvalue, attributes);
273 return pass();
274 }
275 function attvalue(type) {
276 if (type == "keyword") {setStyle = "string"; return cont();}
277 if (type == "string") return cont(attvaluemaybe);
278 return pass();
279 }
280 function attvaluemaybe(type) {
281 if (type == "string") return cont(attvaluemaybe);
282 else return pass();
283 }
284 return {
285 startState: function() {
286 return {tokenize: inText, cc: [], indented: 0, startOfLine: true, pluginName: null, context: null};
287 },
288 token: function(stream, state) {
289 if (stream.sol()) {
290 state.startOfLine = true;
291 state.indented = stream.indentation();
292 }
293 if (stream.eatSpace()) return null;
294
295 setStyle = type = pluginName = null;
296 var style = state.tokenize(stream, state);
297 if ((style || type) && style != "comment") {
298 curState = state;
299 while (true) {
300 var comb = state.cc.pop() || element;
301 if (comb(type || style)) break;
302 }
303 }
304 state.startOfLine = false;
305 return setStyle || style;
306 },
307 indent: function(state, textAfter) {
308 var context = state.context;
309 if (context && context.noIndent) return 0;
310 if (context && /^{\//.test(textAfter))
311 context = context.prev;
312 while (context && !context.startOfLine)
313 context = context.prev;
314 if (context) return context.indent + indentUnit;
315 else return 0;
316 },
317 electricChars: "/"
318 };
319 });
320
321 CodeMirror.defineMIME("text/tiki", "tiki");
322
323 });
@@ -1,88 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("toml", function () {
15 return {
16 startState: function () {
17 return {
18 inString: false,
19 stringType: "",
20 lhs: true,
21 inArray: 0
22 };
23 },
24 token: function (stream, state) {
25 //check for state changes
26 if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
27 state.stringType = stream.peek();
28 stream.next(); // Skip quote
29 state.inString = true; // Update state
30 }
31 if (stream.sol() && state.inArray === 0) {
32 state.lhs = true;
33 }
34 //return state
35 if (state.inString) {
36 while (state.inString && !stream.eol()) {
37 if (stream.peek() === state.stringType) {
38 stream.next(); // Skip quote
39 state.inString = false; // Clear flag
40 } else if (stream.peek() === '\\') {
41 stream.next();
42 stream.next();
43 } else {
44 stream.match(/^.[^\\\"\']*/);
45 }
46 }
47 return state.lhs ? "property string" : "string"; // Token style
48 } else if (state.inArray && stream.peek() === ']') {
49 stream.next();
50 state.inArray--;
51 return 'bracket';
52 } else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) {
53 stream.next();//skip closing ]
54 // array of objects has an extra open & close []
55 if (stream.peek() === ']') stream.next();
56 return "atom";
57 } else if (stream.peek() === "#") {
58 stream.skipToEnd();
59 return "comment";
60 } else if (stream.eatSpace()) {
61 return null;
62 } else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) {
63 return "property";
64 } else if (state.lhs && stream.peek() === "=") {
65 stream.next();
66 state.lhs = false;
67 return null;
68 } else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) {
69 return 'atom'; //date
70 } else if (!state.lhs && (stream.match('true') || stream.match('false'))) {
71 return 'atom';
72 } else if (!state.lhs && stream.peek() === '[') {
73 state.inArray++;
74 stream.next();
75 return 'bracket';
76 } else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) {
77 return 'number';
78 } else if (!stream.eatSpace()) {
79 stream.next();
80 }
81 return null;
82 }
83 };
84 });
85
86 CodeMirror.defineMIME('text/x-toml', 'toml');
87
88 });
@@ -1,68 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 require("../../addon/mode/overlay"));
8 else if (typeof define == "function" && define.amd) // AMD
9 define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 "../../addon/mode/overlay"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
16 CodeMirror.defineMode("tornado:inner", function() {
17 var keywords = ["and","as","assert","autoescape","block","break","class","comment","context",
18 "continue","datetime","def","del","elif","else","end","escape","except",
19 "exec","extends","false","finally","for","from","global","if","import","in",
20 "include","is","json_encode","lambda","length","linkify","load","module",
21 "none","not","or","pass","print","put","raise","raw","return","self","set",
22 "squeeze","super","true","try","url_escape","while","with","without","xhtml_escape","yield"];
23 keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
24
25 function tokenBase (stream, state) {
26 stream.eatWhile(/[^\{]/);
27 var ch = stream.next();
28 if (ch == "{") {
29 if (ch = stream.eat(/\{|%|#/)) {
30 state.tokenize = inTag(ch);
31 return "tag";
32 }
33 }
34 }
35 function inTag (close) {
36 if (close == "{") {
37 close = "}";
38 }
39 return function (stream, state) {
40 var ch = stream.next();
41 if ((ch == close) && stream.eat("}")) {
42 state.tokenize = tokenBase;
43 return "tag";
44 }
45 if (stream.match(keywords)) {
46 return "keyword";
47 }
48 return close == "#" ? "comment" : "string";
49 };
50 }
51 return {
52 startState: function () {
53 return {tokenize: tokenBase};
54 },
55 token: function (stream, state) {
56 return state.tokenize(stream, state);
57 }
58 };
59 });
60
61 CodeMirror.defineMode("tornado", function(config) {
62 var htmlBase = CodeMirror.getMode(config, "text/html");
63 var tornadoInner = CodeMirror.getMode(config, "tornado:inner");
64 return CodeMirror.overlayMode(htmlBase, tornadoInner);
65 });
66
67 CodeMirror.defineMIME("text/x-tornado", "tornado");
68 });
@@ -1,160 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("turtle", function(config) {
15 var indentUnit = config.indentUnit;
16 var curPunc;
17
18 function wordRegexp(words) {
19 return new RegExp("^(?:" + words.join("|") + ")$", "i");
20 }
21 var ops = wordRegexp([]);
22 var keywords = wordRegexp(["@prefix", "@base", "a"]);
23 var operatorChars = /[*+\-<>=&|]/;
24
25 function tokenBase(stream, state) {
26 var ch = stream.next();
27 curPunc = null;
28 if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
29 stream.match(/^[^\s\u00a0>]*>?/);
30 return "atom";
31 }
32 else if (ch == "\"" || ch == "'") {
33 state.tokenize = tokenLiteral(ch);
34 return state.tokenize(stream, state);
35 }
36 else if (/[{}\(\),\.;\[\]]/.test(ch)) {
37 curPunc = ch;
38 return null;
39 }
40 else if (ch == "#") {
41 stream.skipToEnd();
42 return "comment";
43 }
44 else if (operatorChars.test(ch)) {
45 stream.eatWhile(operatorChars);
46 return null;
47 }
48 else if (ch == ":") {
49 return "operator";
50 } else {
51 stream.eatWhile(/[_\w\d]/);
52 if(stream.peek() == ":") {
53 return "variable-3";
54 } else {
55 var word = stream.current();
56
57 if(keywords.test(word)) {
58 return "meta";
59 }
60
61 if(ch >= "A" && ch <= "Z") {
62 return "comment";
63 } else {
64 return "keyword";
65 }
66 }
67 var word = stream.current();
68 if (ops.test(word))
69 return null;
70 else if (keywords.test(word))
71 return "meta";
72 else
73 return "variable";
74 }
75 }
76
77 function tokenLiteral(quote) {
78 return function(stream, state) {
79 var escaped = false, ch;
80 while ((ch = stream.next()) != null) {
81 if (ch == quote && !escaped) {
82 state.tokenize = tokenBase;
83 break;
84 }
85 escaped = !escaped && ch == "\\";
86 }
87 return "string";
88 };
89 }
90
91 function pushContext(state, type, col) {
92 state.context = {prev: state.context, indent: state.indent, col: col, type: type};
93 }
94 function popContext(state) {
95 state.indent = state.context.indent;
96 state.context = state.context.prev;
97 }
98
99 return {
100 startState: function() {
101 return {tokenize: tokenBase,
102 context: null,
103 indent: 0,
104 col: 0};
105 },
106
107 token: function(stream, state) {
108 if (stream.sol()) {
109 if (state.context && state.context.align == null) state.context.align = false;
110 state.indent = stream.indentation();
111 }
112 if (stream.eatSpace()) return null;
113 var style = state.tokenize(stream, state);
114
115 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
116 state.context.align = true;
117 }
118
119 if (curPunc == "(") pushContext(state, ")", stream.column());
120 else if (curPunc == "[") pushContext(state, "]", stream.column());
121 else if (curPunc == "{") pushContext(state, "}", stream.column());
122 else if (/[\]\}\)]/.test(curPunc)) {
123 while (state.context && state.context.type == "pattern") popContext(state);
124 if (state.context && curPunc == state.context.type) popContext(state);
125 }
126 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
127 else if (/atom|string|variable/.test(style) && state.context) {
128 if (/[\}\]]/.test(state.context.type))
129 pushContext(state, "pattern", stream.column());
130 else if (state.context.type == "pattern" && !state.context.align) {
131 state.context.align = true;
132 state.context.col = stream.column();
133 }
134 }
135
136 return style;
137 },
138
139 indent: function(state, textAfter) {
140 var firstChar = textAfter && textAfter.charAt(0);
141 var context = state.context;
142 if (/[\]\}]/.test(firstChar))
143 while (context && context.type == "pattern") context = context.prev;
144
145 var closing = context && firstChar == context.type;
146 if (!context)
147 return 0;
148 else if (context.type == "pattern")
149 return context.col;
150 else if (context.align)
151 return context.col + (closing ? 0 : 1);
152 else
153 return context.indent + (closing ? 0 : indentUnit);
154 }
155 };
156 });
157
158 CodeMirror.defineMIME("text/turtle", "turtle");
159
160 });
@@ -1,274 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("vb", function(conf, parserConf) {
15 var ERRORCLASS = 'error';
16
17 function wordRegexp(words) {
18 return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
19 }
20
21 var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]");
22 var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
23 var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
24 var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
25 var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
26 var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
27
28 var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property', 'try'];
29 var middleKeywords = ['else','elseif','case', 'catch'];
30 var endKeywords = ['next','loop'];
31
32 var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'in']);
33 var commonkeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until',
34 'goto', 'byval','byref','new','handles','property', 'return',
35 'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false'];
36 var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single'];
37
38 var keywords = wordRegexp(commonkeywords);
39 var types = wordRegexp(commontypes);
40 var stringPrefixes = '"';
41
42 var opening = wordRegexp(openingKeywords);
43 var middle = wordRegexp(middleKeywords);
44 var closing = wordRegexp(endKeywords);
45 var doubleClosing = wordRegexp(['end']);
46 var doOpening = wordRegexp(['do']);
47
48 var indentInfo = null;
49
50
51
52
53 function indent(_stream, state) {
54 state.currentIndent++;
55 }
56
57 function dedent(_stream, state) {
58 state.currentIndent--;
59 }
60 // tokenizers
61 function tokenBase(stream, state) {
62 if (stream.eatSpace()) {
63 return null;
64 }
65
66 var ch = stream.peek();
67
68 // Handle Comments
69 if (ch === "'") {
70 stream.skipToEnd();
71 return 'comment';
72 }
73
74
75 // Handle Number Literals
76 if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) {
77 var floatLiteral = false;
78 // Floats
79 if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; }
80 else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; }
81 else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; }
82
83 if (floatLiteral) {
84 // Float literals may be "imaginary"
85 stream.eat(/J/i);
86 return 'number';
87 }
88 // Integers
89 var intLiteral = false;
90 // Hex
91 if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
92 // Octal
93 else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
94 // Decimal
95 else if (stream.match(/^[1-9]\d*F?/)) {
96 // Decimal literals may be "imaginary"
97 stream.eat(/J/i);
98 // TODO - Can you have imaginary longs?
99 intLiteral = true;
100 }
101 // Zero by itself with no other piece of number.
102 else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
103 if (intLiteral) {
104 // Integer literals may be "long"
105 stream.eat(/L/i);
106 return 'number';
107 }
108 }
109
110 // Handle Strings
111 if (stream.match(stringPrefixes)) {
112 state.tokenize = tokenStringFactory(stream.current());
113 return state.tokenize(stream, state);
114 }
115
116 // Handle operators and Delimiters
117 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
118 return null;
119 }
120 if (stream.match(doubleOperators)
121 || stream.match(singleOperators)
122 || stream.match(wordOperators)) {
123 return 'operator';
124 }
125 if (stream.match(singleDelimiters)) {
126 return null;
127 }
128 if (stream.match(doOpening)) {
129 indent(stream,state);
130 state.doInCurrentLine = true;
131 return 'keyword';
132 }
133 if (stream.match(opening)) {
134 if (! state.doInCurrentLine)
135 indent(stream,state);
136 else
137 state.doInCurrentLine = false;
138 return 'keyword';
139 }
140 if (stream.match(middle)) {
141 return 'keyword';
142 }
143
144 if (stream.match(doubleClosing)) {
145 dedent(stream,state);
146 dedent(stream,state);
147 return 'keyword';
148 }
149 if (stream.match(closing)) {
150 dedent(stream,state);
151 return 'keyword';
152 }
153
154 if (stream.match(types)) {
155 return 'keyword';
156 }
157
158 if (stream.match(keywords)) {
159 return 'keyword';
160 }
161
162 if (stream.match(identifiers)) {
163 return 'variable';
164 }
165
166 // Handle non-detected items
167 stream.next();
168 return ERRORCLASS;
169 }
170
171 function tokenStringFactory(delimiter) {
172 var singleline = delimiter.length == 1;
173 var OUTCLASS = 'string';
174
175 return function(stream, state) {
176 while (!stream.eol()) {
177 stream.eatWhile(/[^'"]/);
178 if (stream.match(delimiter)) {
179 state.tokenize = tokenBase;
180 return OUTCLASS;
181 } else {
182 stream.eat(/['"]/);
183 }
184 }
185 if (singleline) {
186 if (parserConf.singleLineStringErrors) {
187 return ERRORCLASS;
188 } else {
189 state.tokenize = tokenBase;
190 }
191 }
192 return OUTCLASS;
193 };
194 }
195
196
197 function tokenLexer(stream, state) {
198 var style = state.tokenize(stream, state);
199 var current = stream.current();
200
201 // Handle '.' connected identifiers
202 if (current === '.') {
203 style = state.tokenize(stream, state);
204 current = stream.current();
205 if (style === 'variable') {
206 return 'variable';
207 } else {
208 return ERRORCLASS;
209 }
210 }
211
212
213 var delimiter_index = '[({'.indexOf(current);
214 if (delimiter_index !== -1) {
215 indent(stream, state );
216 }
217 if (indentInfo === 'dedent') {
218 if (dedent(stream, state)) {
219 return ERRORCLASS;
220 }
221 }
222 delimiter_index = '])}'.indexOf(current);
223 if (delimiter_index !== -1) {
224 if (dedent(stream, state)) {
225 return ERRORCLASS;
226 }
227 }
228
229 return style;
230 }
231
232 var external = {
233 electricChars:"dDpPtTfFeE ",
234 startState: function() {
235 return {
236 tokenize: tokenBase,
237 lastToken: null,
238 currentIndent: 0,
239 nextLineIndent: 0,
240 doInCurrentLine: false
241
242
243 };
244 },
245
246 token: function(stream, state) {
247 if (stream.sol()) {
248 state.currentIndent += state.nextLineIndent;
249 state.nextLineIndent = 0;
250 state.doInCurrentLine = 0;
251 }
252 var style = tokenLexer(stream, state);
253
254 state.lastToken = {style:style, content: stream.current()};
255
256
257
258 return style;
259 },
260
261 indent: function(state, textAfter) {
262 var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
263 if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
264 if(state.currentIndent < 0) return 0;
265 return state.currentIndent * conf.indentUnit;
266 }
267
268 };
269 return external;
270 });
271
272 CodeMirror.defineMIME("text/x-vb", "vb");
273
274 });
@@ -1,350 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 /*
5 For extra ASP classic objects, initialize CodeMirror instance with this option:
6 isASP: true
7
8 E.G.:
9 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
10 lineNumbers: true,
11 isASP: true
12 });
13 */
14
15 (function(mod) {
16 if (typeof exports == "object" && typeof module == "object") // CommonJS
17 mod(require("../../lib/codemirror"));
18 else if (typeof define == "function" && define.amd) // AMD
19 define(["../../lib/codemirror"], mod);
20 else // Plain browser env
21 mod(CodeMirror);
22 })(function(CodeMirror) {
23 "use strict";
24
25 CodeMirror.defineMode("vbscript", function(conf, parserConf) {
26 var ERRORCLASS = 'error';
27
28 function wordRegexp(words) {
29 return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
30 }
31
32 var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
33 var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
34 var singleDelimiters = new RegExp('^[\\.,]');
35 var brakets = new RegExp('^[\\(\\)]');
36 var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
37
38 var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
39 var middleKeywords = ['else','elseif','case'];
40 var endKeywords = ['next','loop','wend'];
41
42 var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']);
43 var commonkeywords = ['dim', 'redim', 'then', 'until', 'randomize',
44 'byval','byref','new','property', 'exit', 'in',
45 'const','private', 'public',
46 'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me'];
47
48 //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx
49 var atomWords = ['true', 'false', 'nothing', 'empty', 'null'];
50 //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx
51 var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart',
52 'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject',
53 'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left',
54 'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round',
55 'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp',
56 'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year'];
57
58 //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx
59 var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare',
60 'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek',
61 'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError',
62 'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2',
63 'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo',
64 'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse',
65 'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray'];
66 //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx
67 var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp'];
68 var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count'];
69 var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit'];
70
71 var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application'];
72 var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response
73 'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request
74 'contents', 'staticobjects', //application
75 'codepage', 'lcid', 'sessionid', 'timeout', //session
76 'scripttimeout']; //server
77 var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response
78 'binaryread', //request
79 'remove', 'removeall', 'lock', 'unlock', //application
80 'abandon', //session
81 'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server
82
83 var knownWords = knownMethods.concat(knownProperties);
84
85 builtinObjsWords = builtinObjsWords.concat(builtinConsts);
86
87 if (conf.isASP){
88 builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords);
89 knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties);
90 };
91
92 var keywords = wordRegexp(commonkeywords);
93 var atoms = wordRegexp(atomWords);
94 var builtinFuncs = wordRegexp(builtinFuncsWords);
95 var builtinObjs = wordRegexp(builtinObjsWords);
96 var known = wordRegexp(knownWords);
97 var stringPrefixes = '"';
98
99 var opening = wordRegexp(openingKeywords);
100 var middle = wordRegexp(middleKeywords);
101 var closing = wordRegexp(endKeywords);
102 var doubleClosing = wordRegexp(['end']);
103 var doOpening = wordRegexp(['do']);
104 var noIndentWords = wordRegexp(['on error resume next', 'exit']);
105 var comment = wordRegexp(['rem']);
106
107
108 function indent(_stream, state) {
109 state.currentIndent++;
110 }
111
112 function dedent(_stream, state) {
113 state.currentIndent--;
114 }
115 // tokenizers
116 function tokenBase(stream, state) {
117 if (stream.eatSpace()) {
118 return 'space';
119 //return null;
120 }
121
122 var ch = stream.peek();
123
124 // Handle Comments
125 if (ch === "'") {
126 stream.skipToEnd();
127 return 'comment';
128 }
129 if (stream.match(comment)){
130 stream.skipToEnd();
131 return 'comment';
132 }
133
134
135 // Handle Number Literals
136 if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) {
137 var floatLiteral = false;
138 // Floats
139 if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; }
140 else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
141 else if (stream.match(/^\.\d+/)) { floatLiteral = true; }
142
143 if (floatLiteral) {
144 // Float literals may be "imaginary"
145 stream.eat(/J/i);
146 return 'number';
147 }
148 // Integers
149 var intLiteral = false;
150 // Hex
151 if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
152 // Octal
153 else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
154 // Decimal
155 else if (stream.match(/^[1-9]\d*F?/)) {
156 // Decimal literals may be "imaginary"
157 stream.eat(/J/i);
158 // TODO - Can you have imaginary longs?
159 intLiteral = true;
160 }
161 // Zero by itself with no other piece of number.
162 else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
163 if (intLiteral) {
164 // Integer literals may be "long"
165 stream.eat(/L/i);
166 return 'number';
167 }
168 }
169
170 // Handle Strings
171 if (stream.match(stringPrefixes)) {
172 state.tokenize = tokenStringFactory(stream.current());
173 return state.tokenize(stream, state);
174 }
175
176 // Handle operators and Delimiters
177 if (stream.match(doubleOperators)
178 || stream.match(singleOperators)
179 || stream.match(wordOperators)) {
180 return 'operator';
181 }
182 if (stream.match(singleDelimiters)) {
183 return null;
184 }
185
186 if (stream.match(brakets)) {
187 return "bracket";
188 }
189
190 if (stream.match(noIndentWords)) {
191 state.doInCurrentLine = true;
192
193 return 'keyword';
194 }
195
196 if (stream.match(doOpening)) {
197 indent(stream,state);
198 state.doInCurrentLine = true;
199
200 return 'keyword';
201 }
202 if (stream.match(opening)) {
203 if (! state.doInCurrentLine)
204 indent(stream,state);
205 else
206 state.doInCurrentLine = false;
207
208 return 'keyword';
209 }
210 if (stream.match(middle)) {
211 return 'keyword';
212 }
213
214
215 if (stream.match(doubleClosing)) {
216 dedent(stream,state);
217 dedent(stream,state);
218
219 return 'keyword';
220 }
221 if (stream.match(closing)) {
222 if (! state.doInCurrentLine)
223 dedent(stream,state);
224 else
225 state.doInCurrentLine = false;
226
227 return 'keyword';
228 }
229
230 if (stream.match(keywords)) {
231 return 'keyword';
232 }
233
234 if (stream.match(atoms)) {
235 return 'atom';
236 }
237
238 if (stream.match(known)) {
239 return 'variable-2';
240 }
241
242 if (stream.match(builtinFuncs)) {
243 return 'builtin';
244 }
245
246 if (stream.match(builtinObjs)){
247 return 'variable-2';
248 }
249
250 if (stream.match(identifiers)) {
251 return 'variable';
252 }
253
254 // Handle non-detected items
255 stream.next();
256 return ERRORCLASS;
257 }
258
259 function tokenStringFactory(delimiter) {
260 var singleline = delimiter.length == 1;
261 var OUTCLASS = 'string';
262
263 return function(stream, state) {
264 while (!stream.eol()) {
265 stream.eatWhile(/[^'"]/);
266 if (stream.match(delimiter)) {
267 state.tokenize = tokenBase;
268 return OUTCLASS;
269 } else {
270 stream.eat(/['"]/);
271 }
272 }
273 if (singleline) {
274 if (parserConf.singleLineStringErrors) {
275 return ERRORCLASS;
276 } else {
277 state.tokenize = tokenBase;
278 }
279 }
280 return OUTCLASS;
281 };
282 }
283
284
285 function tokenLexer(stream, state) {
286 var style = state.tokenize(stream, state);
287 var current = stream.current();
288
289 // Handle '.' connected identifiers
290 if (current === '.') {
291 style = state.tokenize(stream, state);
292
293 current = stream.current();
294 if (style && (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword')){//|| knownWords.indexOf(current.substring(1)) > -1) {
295 if (style === 'builtin' || style === 'keyword') style='variable';
296 if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2';
297
298 return style;
299 } else {
300 return ERRORCLASS;
301 }
302 }
303
304 return style;
305 }
306
307 var external = {
308 electricChars:"dDpPtTfFeE ",
309 startState: function() {
310 return {
311 tokenize: tokenBase,
312 lastToken: null,
313 currentIndent: 0,
314 nextLineIndent: 0,
315 doInCurrentLine: false,
316 ignoreKeyword: false
317
318
319 };
320 },
321
322 token: function(stream, state) {
323 if (stream.sol()) {
324 state.currentIndent += state.nextLineIndent;
325 state.nextLineIndent = 0;
326 state.doInCurrentLine = 0;
327 }
328 var style = tokenLexer(stream, state);
329
330 state.lastToken = {style:style, content: stream.current()};
331
332 if (style==='space') style=null;
333
334 return style;
335 },
336
337 indent: function(state, textAfter) {
338 var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
339 if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
340 if(state.currentIndent < 0) return 0;
341 return state.currentIndent * conf.indentUnit;
342 }
343
344 };
345 return external;
346 });
347
348 CodeMirror.defineMIME("text/vbscript", "vbscript");
349
350 });
@@ -1,201 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("velocity", function() {
15 function parseWords(str) {
16 var obj = {}, words = str.split(" ");
17 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 return obj;
19 }
20
21 var keywords = parseWords("#end #else #break #stop #[[ #]] " +
22 "#{end} #{else} #{break} #{stop}");
23 var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " +
24 "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}");
25 var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent.count $foreach.parent.hasNext $foreach.parent.first $foreach.parent.last $foreach.parent $velocityCount $!bodyContent $bodyContent");
26 var isOperatorChar = /[+\-*&%=<>!?:\/|]/;
27
28 function chain(stream, state, f) {
29 state.tokenize = f;
30 return f(stream, state);
31 }
32 function tokenBase(stream, state) {
33 var beforeParams = state.beforeParams;
34 state.beforeParams = false;
35 var ch = stream.next();
36 // start of unparsed string?
37 if ((ch == "'") && state.inParams) {
38 state.lastTokenWasBuiltin = false;
39 return chain(stream, state, tokenString(ch));
40 }
41 // start of parsed string?
42 else if ((ch == '"')) {
43 state.lastTokenWasBuiltin = false;
44 if (state.inString) {
45 state.inString = false;
46 return "string";
47 }
48 else if (state.inParams)
49 return chain(stream, state, tokenString(ch));
50 }
51 // is it one of the special signs []{}().,;? Seperator?
52 else if (/[\[\]{}\(\),;\.]/.test(ch)) {
53 if (ch == "(" && beforeParams)
54 state.inParams = true;
55 else if (ch == ")") {
56 state.inParams = false;
57 state.lastTokenWasBuiltin = true;
58 }
59 return null;
60 }
61 // start of a number value?
62 else if (/\d/.test(ch)) {
63 state.lastTokenWasBuiltin = false;
64 stream.eatWhile(/[\w\.]/);
65 return "number";
66 }
67 // multi line comment?
68 else if (ch == "#" && stream.eat("*")) {
69 state.lastTokenWasBuiltin = false;
70 return chain(stream, state, tokenComment);
71 }
72 // unparsed content?
73 else if (ch == "#" && stream.match(/ *\[ *\[/)) {
74 state.lastTokenWasBuiltin = false;
75 return chain(stream, state, tokenUnparsed);
76 }
77 // single line comment?
78 else if (ch == "#" && stream.eat("#")) {
79 state.lastTokenWasBuiltin = false;
80 stream.skipToEnd();
81 return "comment";
82 }
83 // variable?
84 else if (ch == "$") {
85 stream.eatWhile(/[\w\d\$_\.{}]/);
86 // is it one of the specials?
87 if (specials && specials.propertyIsEnumerable(stream.current())) {
88 return "keyword";
89 }
90 else {
91 state.lastTokenWasBuiltin = true;
92 state.beforeParams = true;
93 return "builtin";
94 }
95 }
96 // is it a operator?
97 else if (isOperatorChar.test(ch)) {
98 state.lastTokenWasBuiltin = false;
99 stream.eatWhile(isOperatorChar);
100 return "operator";
101 }
102 else {
103 // get the whole word
104 stream.eatWhile(/[\w\$_{}@]/);
105 var word = stream.current();
106 // is it one of the listed keywords?
107 if (keywords && keywords.propertyIsEnumerable(word))
108 return "keyword";
109 // is it one of the listed functions?
110 if (functions && functions.propertyIsEnumerable(word) ||
111 (stream.current().match(/^#@?[a-z0-9_]+ *$/i) && stream.peek()=="(") &&
112 !(functions && functions.propertyIsEnumerable(word.toLowerCase()))) {
113 state.beforeParams = true;
114 state.lastTokenWasBuiltin = false;
115 return "keyword";
116 }
117 if (state.inString) {
118 state.lastTokenWasBuiltin = false;
119 return "string";
120 }
121 if (stream.pos > word.length && stream.string.charAt(stream.pos-word.length-1)=="." && state.lastTokenWasBuiltin)
122 return "builtin";
123 // default: just a "word"
124 state.lastTokenWasBuiltin = false;
125 return null;
126 }
127 }
128
129 function tokenString(quote) {
130 return function(stream, state) {
131 var escaped = false, next, end = false;
132 while ((next = stream.next()) != null) {
133 if ((next == quote) && !escaped) {
134 end = true;
135 break;
136 }
137 if (quote=='"' && stream.peek() == '$' && !escaped) {
138 state.inString = true;
139 end = true;
140 break;
141 }
142 escaped = !escaped && next == "\\";
143 }
144 if (end) state.tokenize = tokenBase;
145 return "string";
146 };
147 }
148
149 function tokenComment(stream, state) {
150 var maybeEnd = false, ch;
151 while (ch = stream.next()) {
152 if (ch == "#" && maybeEnd) {
153 state.tokenize = tokenBase;
154 break;
155 }
156 maybeEnd = (ch == "*");
157 }
158 return "comment";
159 }
160
161 function tokenUnparsed(stream, state) {
162 var maybeEnd = 0, ch;
163 while (ch = stream.next()) {
164 if (ch == "#" && maybeEnd == 2) {
165 state.tokenize = tokenBase;
166 break;
167 }
168 if (ch == "]")
169 maybeEnd++;
170 else if (ch != " ")
171 maybeEnd = 0;
172 }
173 return "meta";
174 }
175 // Interface
176
177 return {
178 startState: function() {
179 return {
180 tokenize: tokenBase,
181 beforeParams: false,
182 inParams: false,
183 inString: false,
184 lastTokenWasBuiltin: false
185 };
186 },
187
188 token: function(stream, state) {
189 if (stream.eatSpace()) return null;
190 return state.tokenize(stream, state);
191 },
192 blockCommentStart: "#*",
193 blockCommentEnd: "*#",
194 lineComment: "##",
195 fold: "velocity"
196 };
197 });
198
199 CodeMirror.defineMIME("text/velocity", "velocity");
200
201 });
@@ -1,364 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("verilog", function(config, parserConfig) {
15
16 var indentUnit = config.indentUnit,
17 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
18 dontAlignCalls = parserConfig.dontAlignCalls,
19 noIndentKeywords = parserConfig.noIndentKeywords || [],
20 multiLineStrings = parserConfig.multiLineStrings;
21
22 function words(str) {
23 var obj = {}, words = str.split(" ");
24 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
25 return obj;
26 }
27
28 /**
29 * Keywords from IEEE 1800-2012
30 */
31 var keywords = words(
32 "accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind " +
33 "bins binsof bit break buf bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config " +
34 "const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable " +
35 "dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup " +
36 "endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask " +
37 "enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin " +
38 "function generate genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import " +
39 "incdir include initial inout input inside instance int integer interconnect interface intersect join join_any " +
40 "join_none large let liblist library local localparam logic longint macromodule matches medium modport module " +
41 "nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 null or output package packed " +
42 "parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup " +
43 "pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg " +
44 "reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime " +
45 "s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify " +
46 "specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on " +
47 "table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior " +
48 "trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void " +
49 "wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor");
50
51 /** Operators from IEEE 1800-2012
52 unary_operator ::=
53 + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
54 binary_operator ::=
55 + | - | * | / | % | == | != | === | !== | ==? | !=? | && | || | **
56 | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<<
57 | -> | <->
58 inc_or_dec_operator ::= ++ | --
59 unary_module_path_operator ::=
60 ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
61 binary_module_path_operator ::=
62 == | != | && | || | & | | | ^ | ^~ | ~^
63 */
64 var isOperatorChar = /[\+\-\*\/!~&|^%=?:]/;
65 var isBracketChar = /[\[\]{}()]/;
66
67 var unsignedNumber = /\d[0-9_]*/;
68 var decimalLiteral = /\d*\s*'s?d\s*\d[0-9_]*/i;
69 var binaryLiteral = /\d*\s*'s?b\s*[xz01][xz01_]*/i;
70 var octLiteral = /\d*\s*'s?o\s*[xz0-7][xz0-7_]*/i;
71 var hexLiteral = /\d*\s*'s?h\s*[0-9a-fxz?][0-9a-fxz?_]*/i;
72 var realLiteral = /(\d[\d_]*(\.\d[\d_]*)?E-?[\d_]+)|(\d[\d_]*\.\d[\d_]*)/i;
73
74 var closingBracketOrWord = /^((\w+)|[)}\]])/;
75 var closingBracket = /[)}\]]/;
76
77 var curPunc;
78 var curKeyword;
79
80 // Block openings which are closed by a matching keyword in the form of ("end" + keyword)
81 // E.g. "task" => "endtask"
82 var blockKeywords = words(
83 "case checker class clocking config function generate interface module package" +
84 "primitive program property specify sequence table task"
85 );
86
87 // Opening/closing pairs
88 var openClose = {};
89 for (var keyword in blockKeywords) {
90 openClose[keyword] = "end" + keyword;
91 }
92 openClose["begin"] = "end";
93 openClose["casex"] = "endcase";
94 openClose["casez"] = "endcase";
95 openClose["do" ] = "while";
96 openClose["fork" ] = "join;join_any;join_none";
97 openClose["covergroup"] = "endgroup";
98
99 for (var i in noIndentKeywords) {
100 var keyword = noIndentKeywords[i];
101 if (openClose[keyword]) {
102 openClose[keyword] = undefined;
103 }
104 }
105
106 // Keywords which open statements that are ended with a semi-colon
107 var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while");
108
109 function tokenBase(stream, state) {
110 var ch = stream.peek();
111 if (/[,;:\.]/.test(ch)) {
112 curPunc = stream.next();
113 return null;
114 }
115 if (isBracketChar.test(ch)) {
116 curPunc = stream.next();
117 return "bracket";
118 }
119 // Macros (tick-defines)
120 if (ch == '`') {
121 stream.next();
122 if (stream.eatWhile(/[\w\$_]/)) {
123 return "def";
124 } else {
125 return null;
126 }
127 }
128 // System calls
129 if (ch == '$') {
130 stream.next();
131 if (stream.eatWhile(/[\w\$_]/)) {
132 return "meta";
133 } else {
134 return null;
135 }
136 }
137 // Time literals
138 if (ch == '#') {
139 stream.next();
140 stream.eatWhile(/[\d_.]/);
141 return "def";
142 }
143 // Strings
144 if (ch == '"') {
145 stream.next();
146 state.tokenize = tokenString(ch);
147 return state.tokenize(stream, state);
148 }
149 // Comments
150 if (ch == "/") {
151 stream.next();
152 if (stream.eat("*")) {
153 state.tokenize = tokenComment;
154 return tokenComment(stream, state);
155 }
156 if (stream.eat("/")) {
157 stream.skipToEnd();
158 return "comment";
159 }
160 stream.backUp(1);
161 }
162
163 // Numeric literals
164 if (stream.match(realLiteral) ||
165 stream.match(decimalLiteral) ||
166 stream.match(binaryLiteral) ||
167 stream.match(octLiteral) ||
168 stream.match(hexLiteral) ||
169 stream.match(unsignedNumber) ||
170 stream.match(realLiteral)) {
171 return "number";
172 }
173
174 // Operators
175 if (stream.eatWhile(isOperatorChar)) {
176 return "meta";
177 }
178
179 // Keywords / plain variables
180 if (stream.eatWhile(/[\w\$_]/)) {
181 var cur = stream.current();
182 if (keywords[cur]) {
183 if (openClose[cur]) {
184 curPunc = "newblock";
185 }
186 if (statementKeywords[cur]) {
187 curPunc = "newstatement";
188 }
189 curKeyword = cur;
190 return "keyword";
191 }
192 return "variable";
193 }
194
195 stream.next();
196 return null;
197 }
198
199 function tokenString(quote) {
200 return function(stream, state) {
201 var escaped = false, next, end = false;
202 while ((next = stream.next()) != null) {
203 if (next == quote && !escaped) {end = true; break;}
204 escaped = !escaped && next == "\\";
205 }
206 if (end || !(escaped || multiLineStrings))
207 state.tokenize = tokenBase;
208 return "string";
209 };
210 }
211
212 function tokenComment(stream, state) {
213 var maybeEnd = false, ch;
214 while (ch = stream.next()) {
215 if (ch == "/" && maybeEnd) {
216 state.tokenize = tokenBase;
217 break;
218 }
219 maybeEnd = (ch == "*");
220 }
221 return "comment";
222 }
223
224 function Context(indented, column, type, align, prev) {
225 this.indented = indented;
226 this.column = column;
227 this.type = type;
228 this.align = align;
229 this.prev = prev;
230 }
231 function pushContext(state, col, type) {
232 var indent = state.indented;
233 var c = new Context(indent, col, type, null, state.context);
234 return state.context = c;
235 }
236 function popContext(state) {
237 var t = state.context.type;
238 if (t == ")" || t == "]" || t == "}") {
239 state.indented = state.context.indented;
240 }
241 return state.context = state.context.prev;
242 }
243
244 function isClosing(text, contextClosing) {
245 if (text == contextClosing) {
246 return true;
247 } else {
248 // contextClosing may be mulitple keywords separated by ;
249 var closingKeywords = contextClosing.split(";");
250 for (var i in closingKeywords) {
251 if (text == closingKeywords[i]) {
252 return true;
253 }
254 }
255 return false;
256 }
257 }
258
259 function buildElectricInputRegEx() {
260 // Reindentation should occur on any bracket char: {}()[]
261 // or on a match of any of the block closing keywords, at
262 // the end of a line
263 var allClosings = [];
264 for (var i in openClose) {
265 if (openClose[i]) {
266 var closings = openClose[i].split(";");
267 for (var j in closings) {
268 allClosings.push(closings[j]);
269 }
270 }
271 }
272 var re = new RegExp("[{}()\\[\\]]|(" + allClosings.join("|") + ")$");
273 return re;
274 }
275
276 // Interface
277 return {
278
279 // Regex to force current line to reindent
280 electricInput: buildElectricInputRegEx(),
281
282 startState: function(basecolumn) {
283 return {
284 tokenize: null,
285 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
286 indented: 0,
287 startOfLine: true
288 };
289 },
290
291 token: function(stream, state) {
292 var ctx = state.context;
293 if (stream.sol()) {
294 if (ctx.align == null) ctx.align = false;
295 state.indented = stream.indentation();
296 state.startOfLine = true;
297 }
298 if (stream.eatSpace()) return null;
299 curPunc = null;
300 curKeyword = null;
301 var style = (state.tokenize || tokenBase)(stream, state);
302 if (style == "comment" || style == "meta" || style == "variable") return style;
303 if (ctx.align == null) ctx.align = true;
304
305 if (curPunc == ctx.type) {
306 popContext(state);
307 }
308 else if ((curPunc == ";" && ctx.type == "statement") ||
309 (ctx.type && isClosing(curKeyword, ctx.type))) {
310 ctx = popContext(state);
311 while (ctx && ctx.type == "statement") ctx = popContext(state);
312 }
313 else if (curPunc == "{") { pushContext(state, stream.column(), "}"); }
314 else if (curPunc == "[") { pushContext(state, stream.column(), "]"); }
315 else if (curPunc == "(") { pushContext(state, stream.column(), ")"); }
316 else if (ctx && ctx.type == "endcase" && curPunc == ":") { pushContext(state, stream.column(), "statement"); }
317 else if (curPunc == "newstatement") {
318 pushContext(state, stream.column(), "statement");
319 } else if (curPunc == "newblock") {
320 if (curKeyword == "function" && ctx && (ctx.type == "statement" || ctx.type == "endgroup")) {
321 // The 'function' keyword can appear in some other contexts where it actually does not
322 // indicate a function (import/export DPI and covergroup definitions).
323 // Do nothing in this case
324 } else if (curKeyword == "task" && ctx && ctx.type == "statement") {
325 // Same thing for task
326 } else {
327 var close = openClose[curKeyword];
328 pushContext(state, stream.column(), close);
329 }
330 }
331
332 state.startOfLine = false;
333 return style;
334 },
335
336 indent: function(state, textAfter) {
337 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
338 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
339 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
340 var closing = false;
341 var possibleClosing = textAfter.match(closingBracketOrWord);
342 if (possibleClosing) {
343 closing = isClosing(possibleClosing[0], ctx.type);
344 }
345 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
346 else if (closingBracket.test(ctx.type) && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1);
347 else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
348 else return ctx.indented + (closing ? 0 : indentUnit);
349 },
350
351 blockCommentStart: "/*",
352 blockCommentEnd: "*/",
353 lineComment: "//"
354 };
355 });
356
357 CodeMirror.defineMIME("text/x-verilog", {
358 name: "verilog"
359 });
360 CodeMirror.defineMIME("text/x-systemverilog", {
361 name: "systemverilog"
362 });
363
364 });
@@ -1,384 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("xml", function(config, parserConfig) {
15 var indentUnit = config.indentUnit;
16 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
17 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
18 if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
19
20 var Kludges = parserConfig.htmlMode ? {
21 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
22 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
23 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
24 'track': true, 'wbr': true, 'menuitem': true},
25 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
26 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
27 'th': true, 'tr': true},
28 contextGrabbers: {
29 'dd': {'dd': true, 'dt': true},
30 'dt': {'dd': true, 'dt': true},
31 'li': {'li': true},
32 'option': {'option': true, 'optgroup': true},
33 'optgroup': {'optgroup': true},
34 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
35 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
36 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
37 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
38 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
39 'rp': {'rp': true, 'rt': true},
40 'rt': {'rp': true, 'rt': true},
41 'tbody': {'tbody': true, 'tfoot': true},
42 'td': {'td': true, 'th': true},
43 'tfoot': {'tbody': true},
44 'th': {'td': true, 'th': true},
45 'thead': {'tbody': true, 'tfoot': true},
46 'tr': {'tr': true}
47 },
48 doNotIndent: {"pre": true},
49 allowUnquoted: true,
50 allowMissing: true,
51 caseFold: true
52 } : {
53 autoSelfClosers: {},
54 implicitlyClosed: {},
55 contextGrabbers: {},
56 doNotIndent: {},
57 allowUnquoted: false,
58 allowMissing: false,
59 caseFold: false
60 };
61 var alignCDATA = parserConfig.alignCDATA;
62
63 // Return variables for tokenizers
64 var type, setStyle;
65
66 function inText(stream, state) {
67 function chain(parser) {
68 state.tokenize = parser;
69 return parser(stream, state);
70 }
71
72 var ch = stream.next();
73 if (ch == "<") {
74 if (stream.eat("!")) {
75 if (stream.eat("[")) {
76 if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
77 else return null;
78 } else if (stream.match("--")) {
79 return chain(inBlock("comment", "-->"));
80 } else if (stream.match("DOCTYPE", true, true)) {
81 stream.eatWhile(/[\w\._\-]/);
82 return chain(doctype(1));
83 } else {
84 return null;
85 }
86 } else if (stream.eat("?")) {
87 stream.eatWhile(/[\w\._\-]/);
88 state.tokenize = inBlock("meta", "?>");
89 return "meta";
90 } else {
91 type = stream.eat("/") ? "closeTag" : "openTag";
92 state.tokenize = inTag;
93 return "tag bracket";
94 }
95 } else if (ch == "&") {
96 var ok;
97 if (stream.eat("#")) {
98 if (stream.eat("x")) {
99 ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
100 } else {
101 ok = stream.eatWhile(/[\d]/) && stream.eat(";");
102 }
103 } else {
104 ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
105 }
106 return ok ? "atom" : "error";
107 } else {
108 stream.eatWhile(/[^&<]/);
109 return null;
110 }
111 }
112
113 function inTag(stream, state) {
114 var ch = stream.next();
115 if (ch == ">" || (ch == "/" && stream.eat(">"))) {
116 state.tokenize = inText;
117 type = ch == ">" ? "endTag" : "selfcloseTag";
118 return "tag bracket";
119 } else if (ch == "=") {
120 type = "equals";
121 return null;
122 } else if (ch == "<") {
123 state.tokenize = inText;
124 state.state = baseState;
125 state.tagName = state.tagStart = null;
126 var next = state.tokenize(stream, state);
127 return next ? next + " tag error" : "tag error";
128 } else if (/[\'\"]/.test(ch)) {
129 state.tokenize = inAttribute(ch);
130 state.stringStartCol = stream.column();
131 return state.tokenize(stream, state);
132 } else {
133 stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
134 return "word";
135 }
136 }
137
138 function inAttribute(quote) {
139 var closure = function(stream, state) {
140 while (!stream.eol()) {
141 if (stream.next() == quote) {
142 state.tokenize = inTag;
143 break;
144 }
145 }
146 return "string";
147 };
148 closure.isInAttribute = true;
149 return closure;
150 }
151
152 function inBlock(style, terminator) {
153 return function(stream, state) {
154 while (!stream.eol()) {
155 if (stream.match(terminator)) {
156 state.tokenize = inText;
157 break;
158 }
159 stream.next();
160 }
161 return style;
162 };
163 }
164 function doctype(depth) {
165 return function(stream, state) {
166 var ch;
167 while ((ch = stream.next()) != null) {
168 if (ch == "<") {
169 state.tokenize = doctype(depth + 1);
170 return state.tokenize(stream, state);
171 } else if (ch == ">") {
172 if (depth == 1) {
173 state.tokenize = inText;
174 break;
175 } else {
176 state.tokenize = doctype(depth - 1);
177 return state.tokenize(stream, state);
178 }
179 }
180 }
181 return "meta";
182 };
183 }
184
185 function Context(state, tagName, startOfLine) {
186 this.prev = state.context;
187 this.tagName = tagName;
188 this.indent = state.indented;
189 this.startOfLine = startOfLine;
190 if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
191 this.noIndent = true;
192 }
193 function popContext(state) {
194 if (state.context) state.context = state.context.prev;
195 }
196 function maybePopContext(state, nextTagName) {
197 var parentTagName;
198 while (true) {
199 if (!state.context) {
200 return;
201 }
202 parentTagName = state.context.tagName;
203 if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
204 !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
205 return;
206 }
207 popContext(state);
208 }
209 }
210
211 function baseState(type, stream, state) {
212 if (type == "openTag") {
213 state.tagStart = stream.column();
214 return tagNameState;
215 } else if (type == "closeTag") {
216 return closeTagNameState;
217 } else {
218 return baseState;
219 }
220 }
221 function tagNameState(type, stream, state) {
222 if (type == "word") {
223 state.tagName = stream.current();
224 setStyle = "tag";
225 return attrState;
226 } else {
227 setStyle = "error";
228 return tagNameState;
229 }
230 }
231 function closeTagNameState(type, stream, state) {
232 if (type == "word") {
233 var tagName = stream.current();
234 if (state.context && state.context.tagName != tagName &&
235 Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
236 popContext(state);
237 if (state.context && state.context.tagName == tagName) {
238 setStyle = "tag";
239 return closeState;
240 } else {
241 setStyle = "tag error";
242 return closeStateErr;
243 }
244 } else {
245 setStyle = "error";
246 return closeStateErr;
247 }
248 }
249
250 function closeState(type, _stream, state) {
251 if (type != "endTag") {
252 setStyle = "error";
253 return closeState;
254 }
255 popContext(state);
256 return baseState;
257 }
258 function closeStateErr(type, stream, state) {
259 setStyle = "error";
260 return closeState(type, stream, state);
261 }
262
263 function attrState(type, _stream, state) {
264 if (type == "word") {
265 setStyle = "attribute";
266 return attrEqState;
267 } else if (type == "endTag" || type == "selfcloseTag") {
268 var tagName = state.tagName, tagStart = state.tagStart;
269 state.tagName = state.tagStart = null;
270 if (type == "selfcloseTag" ||
271 Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
272 maybePopContext(state, tagName);
273 } else {
274 maybePopContext(state, tagName);
275 state.context = new Context(state, tagName, tagStart == state.indented);
276 }
277 return baseState;
278 }
279 setStyle = "error";
280 return attrState;
281 }
282 function attrEqState(type, stream, state) {
283 if (type == "equals") return attrValueState;
284 if (!Kludges.allowMissing) setStyle = "error";
285 return attrState(type, stream, state);
286 }
287 function attrValueState(type, stream, state) {
288 if (type == "string") return attrContinuedState;
289 if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
290 setStyle = "error";
291 return attrState(type, stream, state);
292 }
293 function attrContinuedState(type, stream, state) {
294 if (type == "string") return attrContinuedState;
295 return attrState(type, stream, state);
296 }
297
298 return {
299 startState: function() {
300 return {tokenize: inText,
301 state: baseState,
302 indented: 0,
303 tagName: null, tagStart: null,
304 context: null};
305 },
306
307 token: function(stream, state) {
308 if (!state.tagName && stream.sol())
309 state.indented = stream.indentation();
310
311 if (stream.eatSpace()) return null;
312 type = null;
313 var style = state.tokenize(stream, state);
314 if ((style || type) && style != "comment") {
315 setStyle = null;
316 state.state = state.state(type || style, stream, state);
317 if (setStyle)
318 style = setStyle == "error" ? style + " error" : setStyle;
319 }
320 return style;
321 },
322
323 indent: function(state, textAfter, fullLine) {
324 var context = state.context;
325 // Indent multi-line strings (e.g. css).
326 if (state.tokenize.isInAttribute) {
327 if (state.tagStart == state.indented)
328 return state.stringStartCol + 1;
329 else
330 return state.indented + indentUnit;
331 }
332 if (context && context.noIndent) return CodeMirror.Pass;
333 if (state.tokenize != inTag && state.tokenize != inText)
334 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
335 // Indent the starts of attribute names.
336 if (state.tagName) {
337 if (multilineTagIndentPastTag)
338 return state.tagStart + state.tagName.length + 2;
339 else
340 return state.tagStart + indentUnit * multilineTagIndentFactor;
341 }
342 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
343 var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
344 if (tagAfter && tagAfter[1]) { // Closing tag spotted
345 while (context) {
346 if (context.tagName == tagAfter[2]) {
347 context = context.prev;
348 break;
349 } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
350 context = context.prev;
351 } else {
352 break;
353 }
354 }
355 } else if (tagAfter) { // Opening tag spotted
356 while (context) {
357 var grabbers = Kludges.contextGrabbers[context.tagName];
358 if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
359 context = context.prev;
360 else
361 break;
362 }
363 }
364 while (context && !context.startOfLine)
365 context = context.prev;
366 if (context) return context.indent + indentUnit;
367 else return 0;
368 },
369
370 electricInput: /<\/[\s\w:]+>$/,
371 blockCommentStart: "<!--",
372 blockCommentEnd: "-->",
373
374 configuration: parserConfig.htmlMode ? "html" : "xml",
375 helperType: parserConfig.htmlMode ? "html" : "xml"
376 };
377 });
378
379 CodeMirror.defineMIME("text/xml", "xml");
380 CodeMirror.defineMIME("application/xml", "xml");
381 if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
382 CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
383
384 });
@@ -1,447 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("xquery", function() {
15
16 // The keywords object is set to the result of this self executing
17 // function. Each keyword is a property of the keywords object whose
18 // value is {type: atype, style: astyle}
19 var keywords = function(){
20 // conveinence functions used to build keywords object
21 function kw(type) {return {type: type, style: "keyword"};}
22 var A = kw("keyword a")
23 , B = kw("keyword b")
24 , C = kw("keyword c")
25 , operator = kw("operator")
26 , atom = {type: "atom", style: "atom"}
27 , punctuation = {type: "punctuation", style: null}
28 , qualifier = {type: "axis_specifier", style: "qualifier"};
29
30 // kwObj is what is return from this function at the end
31 var kwObj = {
32 'if': A, 'switch': A, 'while': A, 'for': A,
33 'else': B, 'then': B, 'try': B, 'finally': B, 'catch': B,
34 'element': C, 'attribute': C, 'let': C, 'implements': C, 'import': C, 'module': C, 'namespace': C,
35 'return': C, 'super': C, 'this': C, 'throws': C, 'where': C, 'private': C,
36 ',': punctuation,
37 'null': atom, 'fn:false()': atom, 'fn:true()': atom
38 };
39
40 // a list of 'basic' keywords. For each add a property to kwObj with the value of
41 // {type: basic[i], style: "keyword"} e.g. 'after' --> {type: "after", style: "keyword"}
42 var basic = ['after','ancestor','ancestor-or-self','and','as','ascending','assert','attribute','before',
43 'by','case','cast','child','comment','declare','default','define','descendant','descendant-or-self',
44 'descending','document','document-node','element','else','eq','every','except','external','following',
45 'following-sibling','follows','for','function','if','import','in','instance','intersect','item',
46 'let','module','namespace','node','node','of','only','or','order','parent','precedes','preceding',
47 'preceding-sibling','processing-instruction','ref','return','returns','satisfies','schema','schema-element',
48 'self','some','sortby','stable','text','then','to','treat','typeswitch','union','variable','version','where',
49 'xquery', 'empty-sequence'];
50 for(var i=0, l=basic.length; i < l; i++) { kwObj[basic[i]] = kw(basic[i]);};
51
52 // a list of types. For each add a property to kwObj with the value of
53 // {type: "atom", style: "atom"}
54 var types = ['xs:string', 'xs:float', 'xs:decimal', 'xs:double', 'xs:integer', 'xs:boolean', 'xs:date', 'xs:dateTime',
55 'xs:time', 'xs:duration', 'xs:dayTimeDuration', 'xs:time', 'xs:yearMonthDuration', 'numeric', 'xs:hexBinary',
56 'xs:base64Binary', 'xs:anyURI', 'xs:QName', 'xs:byte','xs:boolean','xs:anyURI','xf:yearMonthDuration'];
57 for(var i=0, l=types.length; i < l; i++) { kwObj[types[i]] = atom;};
58
59 // each operator will add a property to kwObj with value of {type: "operator", style: "keyword"}
60 var operators = ['eq', 'ne', 'lt', 'le', 'gt', 'ge', ':=', '=', '>', '>=', '<', '<=', '.', '|', '?', 'and', 'or', 'div', 'idiv', 'mod', '*', '/', '+', '-'];
61 for(var i=0, l=operators.length; i < l; i++) { kwObj[operators[i]] = operator;};
62
63 // each axis_specifiers will add a property to kwObj with value of {type: "axis_specifier", style: "qualifier"}
64 var axis_specifiers = ["self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "parent::",
65 "ancestor::", "ancestor-or-self::", "following::", "preceding::", "following-sibling::", "preceding-sibling::"];
66 for(var i=0, l=axis_specifiers.length; i < l; i++) { kwObj[axis_specifiers[i]] = qualifier; };
67
68 return kwObj;
69 }();
70
71 // Used as scratch variables to communicate multiple values without
72 // consing up tons of objects.
73 var type, content;
74
75 function ret(tp, style, cont) {
76 type = tp; content = cont;
77 return style;
78 }
79
80 function chain(stream, state, f) {
81 state.tokenize = f;
82 return f(stream, state);
83 }
84
85 // the primary mode tokenizer
86 function tokenBase(stream, state) {
87 var ch = stream.next(),
88 mightBeFunction = false,
89 isEQName = isEQNameAhead(stream);
90
91 // an XML tag (if not in some sub, chained tokenizer)
92 if (ch == "<") {
93 if(stream.match("!--", true))
94 return chain(stream, state, tokenXMLComment);
95
96 if(stream.match("![CDATA", false)) {
97 state.tokenize = tokenCDATA;
98 return ret("tag", "tag");
99 }
100
101 if(stream.match("?", false)) {
102 return chain(stream, state, tokenPreProcessing);
103 }
104
105 var isclose = stream.eat("/");
106 stream.eatSpace();
107 var tagName = "", c;
108 while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
109
110 return chain(stream, state, tokenTag(tagName, isclose));
111 }
112 // start code block
113 else if(ch == "{") {
114 pushStateStack(state,{ type: "codeblock"});
115 return ret("", null);
116 }
117 // end code block
118 else if(ch == "}") {
119 popStateStack(state);
120 return ret("", null);
121 }
122 // if we're in an XML block
123 else if(isInXmlBlock(state)) {
124 if(ch == ">")
125 return ret("tag", "tag");
126 else if(ch == "/" && stream.eat(">")) {
127 popStateStack(state);
128 return ret("tag", "tag");
129 }
130 else
131 return ret("word", "variable");
132 }
133 // if a number
134 else if (/\d/.test(ch)) {
135 stream.match(/^\d*(?:\.\d*)?(?:E[+\-]?\d+)?/);
136 return ret("number", "atom");
137 }
138 // comment start
139 else if (ch === "(" && stream.eat(":")) {
140 pushStateStack(state, { type: "comment"});
141 return chain(stream, state, tokenComment);
142 }
143 // quoted string
144 else if ( !isEQName && (ch === '"' || ch === "'"))
145 return chain(stream, state, tokenString(ch));
146 // variable
147 else if(ch === "$") {
148 return chain(stream, state, tokenVariable);
149 }
150 // assignment
151 else if(ch ===":" && stream.eat("=")) {
152 return ret("operator", "keyword");
153 }
154 // open paren
155 else if(ch === "(") {
156 pushStateStack(state, { type: "paren"});
157 return ret("", null);
158 }
159 // close paren
160 else if(ch === ")") {
161 popStateStack(state);
162 return ret("", null);
163 }
164 // open paren
165 else if(ch === "[") {
166 pushStateStack(state, { type: "bracket"});
167 return ret("", null);
168 }
169 // close paren
170 else if(ch === "]") {
171 popStateStack(state);
172 return ret("", null);
173 }
174 else {
175 var known = keywords.propertyIsEnumerable(ch) && keywords[ch];
176
177 // if there's a EQName ahead, consume the rest of the string portion, it's likely a function
178 if(isEQName && ch === '\"') while(stream.next() !== '"'){}
179 if(isEQName && ch === '\'') while(stream.next() !== '\''){}
180
181 // gobble up a word if the character is not known
182 if(!known) stream.eatWhile(/[\w\$_-]/);
183
184 // gobble a colon in the case that is a lib func type call fn:doc
185 var foundColon = stream.eat(":");
186
187 // if there's not a second colon, gobble another word. Otherwise, it's probably an axis specifier
188 // which should get matched as a keyword
189 if(!stream.eat(":") && foundColon) {
190 stream.eatWhile(/[\w\$_-]/);
191 }
192 // if the next non whitespace character is an open paren, this is probably a function (if not a keyword of other sort)
193 if(stream.match(/^[ \t]*\(/, false)) {
194 mightBeFunction = true;
195 }
196 // is the word a keyword?
197 var word = stream.current();
198 known = keywords.propertyIsEnumerable(word) && keywords[word];
199
200 // if we think it's a function call but not yet known,
201 // set style to variable for now for lack of something better
202 if(mightBeFunction && !known) known = {type: "function_call", style: "variable def"};
203
204 // if the previous word was element, attribute, axis specifier, this word should be the name of that
205 if(isInXmlConstructor(state)) {
206 popStateStack(state);
207 return ret("word", "variable", word);
208 }
209 // as previously checked, if the word is element,attribute, axis specifier, call it an "xmlconstructor" and
210 // push the stack so we know to look for it on the next word
211 if(word == "element" || word == "attribute" || known.type == "axis_specifier") pushStateStack(state, {type: "xmlconstructor"});
212
213 // if the word is known, return the details of that else just call this a generic 'word'
214 return known ? ret(known.type, known.style, word) :
215 ret("word", "variable", word);
216 }
217 }
218
219 // handle comments, including nested
220 function tokenComment(stream, state) {
221 var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
222 while (ch = stream.next()) {
223 if (ch == ")" && maybeEnd) {
224 if(nestedCount > 0)
225 nestedCount--;
226 else {
227 popStateStack(state);
228 break;
229 }
230 }
231 else if(ch == ":" && maybeNested) {
232 nestedCount++;
233 }
234 maybeEnd = (ch == ":");
235 maybeNested = (ch == "(");
236 }
237
238 return ret("comment", "comment");
239 }
240
241 // tokenizer for string literals
242 // optionally pass a tokenizer function to set state.tokenize back to when finished
243 function tokenString(quote, f) {
244 return function(stream, state) {
245 var ch;
246
247 if(isInString(state) && stream.current() == quote) {
248 popStateStack(state);
249 if(f) state.tokenize = f;
250 return ret("string", "string");
251 }
252
253 pushStateStack(state, { type: "string", name: quote, tokenize: tokenString(quote, f) });
254
255 // if we're in a string and in an XML block, allow an embedded code block
256 if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
257 state.tokenize = tokenBase;
258 return ret("string", "string");
259 }
260
261
262 while (ch = stream.next()) {
263 if (ch == quote) {
264 popStateStack(state);
265 if(f) state.tokenize = f;
266 break;
267 }
268 else {
269 // if we're in a string and in an XML block, allow an embedded code block in an attribute
270 if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
271 state.tokenize = tokenBase;
272 return ret("string", "string");
273 }
274
275 }
276 }
277
278 return ret("string", "string");
279 };
280 }
281
282 // tokenizer for variables
283 function tokenVariable(stream, state) {
284 var isVariableChar = /[\w\$_-]/;
285
286 // a variable may start with a quoted EQName so if the next character is quote, consume to the next quote
287 if(stream.eat("\"")) {
288 while(stream.next() !== '\"'){};
289 stream.eat(":");
290 } else {
291 stream.eatWhile(isVariableChar);
292 if(!stream.match(":=", false)) stream.eat(":");
293 }
294 stream.eatWhile(isVariableChar);
295 state.tokenize = tokenBase;
296 return ret("variable", "variable");
297 }
298
299 // tokenizer for XML tags
300 function tokenTag(name, isclose) {
301 return function(stream, state) {
302 stream.eatSpace();
303 if(isclose && stream.eat(">")) {
304 popStateStack(state);
305 state.tokenize = tokenBase;
306 return ret("tag", "tag");
307 }
308 // self closing tag without attributes?
309 if(!stream.eat("/"))
310 pushStateStack(state, { type: "tag", name: name, tokenize: tokenBase});
311 if(!stream.eat(">")) {
312 state.tokenize = tokenAttribute;
313 return ret("tag", "tag");
314 }
315 else {
316 state.tokenize = tokenBase;
317 }
318 return ret("tag", "tag");
319 };
320 }
321
322 // tokenizer for XML attributes
323 function tokenAttribute(stream, state) {
324 var ch = stream.next();
325
326 if(ch == "/" && stream.eat(">")) {
327 if(isInXmlAttributeBlock(state)) popStateStack(state);
328 if(isInXmlBlock(state)) popStateStack(state);
329 return ret("tag", "tag");
330 }
331 if(ch == ">") {
332 if(isInXmlAttributeBlock(state)) popStateStack(state);
333 return ret("tag", "tag");
334 }
335 if(ch == "=")
336 return ret("", null);
337 // quoted string
338 if (ch == '"' || ch == "'")
339 return chain(stream, state, tokenString(ch, tokenAttribute));
340
341 if(!isInXmlAttributeBlock(state))
342 pushStateStack(state, { type: "attribute", tokenize: tokenAttribute});
343
344 stream.eat(/[a-zA-Z_:]/);
345 stream.eatWhile(/[-a-zA-Z0-9_:.]/);
346 stream.eatSpace();
347
348 // the case where the attribute has not value and the tag was closed
349 if(stream.match(">", false) || stream.match("/", false)) {
350 popStateStack(state);
351 state.tokenize = tokenBase;
352 }
353
354 return ret("attribute", "attribute");
355 }
356
357 // handle comments, including nested
358 function tokenXMLComment(stream, state) {
359 var ch;
360 while (ch = stream.next()) {
361 if (ch == "-" && stream.match("->", true)) {
362 state.tokenize = tokenBase;
363 return ret("comment", "comment");
364 }
365 }
366 }
367
368
369 // handle CDATA
370 function tokenCDATA(stream, state) {
371 var ch;
372 while (ch = stream.next()) {
373 if (ch == "]" && stream.match("]", true)) {
374 state.tokenize = tokenBase;
375 return ret("comment", "comment");
376 }
377 }
378 }
379
380 // handle preprocessing instructions
381 function tokenPreProcessing(stream, state) {
382 var ch;
383 while (ch = stream.next()) {
384 if (ch == "?" && stream.match(">", true)) {
385 state.tokenize = tokenBase;
386 return ret("comment", "comment meta");
387 }
388 }
389 }
390
391
392 // functions to test the current context of the state
393 function isInXmlBlock(state) { return isIn(state, "tag"); }
394 function isInXmlAttributeBlock(state) { return isIn(state, "attribute"); }
395 function isInXmlConstructor(state) { return isIn(state, "xmlconstructor"); }
396 function isInString(state) { return isIn(state, "string"); }
397
398 function isEQNameAhead(stream) {
399 // assume we've already eaten a quote (")
400 if(stream.current() === '"')
401 return stream.match(/^[^\"]+\"\:/, false);
402 else if(stream.current() === '\'')
403 return stream.match(/^[^\"]+\'\:/, false);
404 else
405 return false;
406 }
407
408 function isIn(state, type) {
409 return (state.stack.length && state.stack[state.stack.length - 1].type == type);
410 }
411
412 function pushStateStack(state, newState) {
413 state.stack.push(newState);
414 }
415
416 function popStateStack(state) {
417 state.stack.pop();
418 var reinstateTokenize = state.stack.length && state.stack[state.stack.length-1].tokenize;
419 state.tokenize = reinstateTokenize || tokenBase;
420 }
421
422 // the interface for the mode API
423 return {
424 startState: function() {
425 return {
426 tokenize: tokenBase,
427 cc: [],
428 stack: []
429 };
430 },
431
432 token: function(stream, state) {
433 if (stream.eatSpace()) return null;
434 var style = state.tokenize(stream, state);
435 return style;
436 },
437
438 blockCommentStart: "(:",
439 blockCommentEnd: ":)"
440
441 };
442
443 });
444
445 CodeMirror.defineMIME("application/xquery", "xquery");
446
447 });
@@ -1,112 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("yaml", function() {
15
16 var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
17 var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
18
19 return {
20 token: function(stream, state) {
21 var ch = stream.peek();
22 var esc = state.escaped;
23 state.escaped = false;
24 /* comments */
25 if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
26 stream.skipToEnd(); return "comment";
27 }
28 if (state.literal && stream.indentation() > state.keyCol) {
29 stream.skipToEnd(); return "string";
30 } else if (state.literal) { state.literal = false; }
31 if (stream.sol()) {
32 state.keyCol = 0;
33 state.pair = false;
34 state.pairStart = false;
35 /* document start */
36 if(stream.match(/---/)) { return "def"; }
37 /* document end */
38 if (stream.match(/\.\.\./)) { return "def"; }
39 /* array list item */
40 if (stream.match(/\s*-\s+/)) { return 'meta'; }
41 }
42 /* inline pairs/lists */
43 if (stream.match(/^(\{|\}|\[|\])/)) {
44 if (ch == '{')
45 state.inlinePairs++;
46 else if (ch == '}')
47 state.inlinePairs--;
48 else if (ch == '[')
49 state.inlineList++;
50 else
51 state.inlineList--;
52 return 'meta';
53 }
54
55 /* list seperator */
56 if (state.inlineList > 0 && !esc && ch == ',') {
57 stream.next();
58 return 'meta';
59 }
60 /* pairs seperator */
61 if (state.inlinePairs > 0 && !esc && ch == ',') {
62 state.keyCol = 0;
63 state.pair = false;
64 state.pairStart = false;
65 stream.next();
66 return 'meta';
67 }
68
69 /* start of value of a pair */
70 if (state.pairStart) {
71 /* block literals */
72 if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
73 /* references */
74 if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
75 /* numbers */
76 if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
77 if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
78 /* keywords */
79 if (stream.match(keywordRegex)) { return 'keyword'; }
80 }
81
82 /* pairs (associative arrays) -> key */
83 if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
84 state.pair = true;
85 state.keyCol = stream.indentation();
86 return "atom";
87 }
88 if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
89
90 /* nothing found, continue */
91 state.pairStart = false;
92 state.escaped = (ch == '\\');
93 stream.next();
94 return null;
95 },
96 startState: function() {
97 return {
98 pair: false,
99 pairStart: false,
100 keyCol: 0,
101 inlinePairs: 0,
102 inlineList: 0,
103 literal: false,
104 escaped: false
105 };
106 }
107 };
108 });
109
110 CodeMirror.defineMIME("text/x-yaml", "yaml");
111
112 });
@@ -1,100 +0,0 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode('z80', function() {
15 var keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i;
16 var keywords2 = /^(call|j[pr]|ret[in]?)\b/i;
17 var keywords3 = /^b_?(call|jump)\b/i;
18 var variables1 = /^(af?|bc?|c|de?|e|hl?|l|i[xy]?|r|sp)\b/i;
19 var variables2 = /^(n?[zc]|p[oe]?|m)\b/i;
20 var errors = /^([hl][xy]|i[xy][hl]|slia|sll)\b/i;
21 var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+)\b/i;
22
23 return {
24 startState: function() {
25 return {context: 0};
26 },
27 token: function(stream, state) {
28 if (!stream.column())
29 state.context = 0;
30
31 if (stream.eatSpace())
32 return null;
33
34 var w;
35
36 if (stream.eatWhile(/\w/)) {
37 w = stream.current();
38
39 if (stream.indentation()) {
40 if (state.context == 1 && variables1.test(w))
41 return 'variable-2';
42
43 if (state.context == 2 && variables2.test(w))
44 return 'variable-3';
45
46 if (keywords1.test(w)) {
47 state.context = 1;
48 return 'keyword';
49 } else if (keywords2.test(w)) {
50 state.context = 2;
51 return 'keyword';
52 } else if (keywords3.test(w)) {
53 state.context = 3;
54 return 'keyword';
55 }
56
57 if (errors.test(w))
58 return 'error';
59 } else if (numbers.test(w)) {
60 return 'number';
61 } else {
62 return null;
63 }
64 } else if (stream.eat(';')) {
65 stream.skipToEnd();
66 return 'comment';
67 } else if (stream.eat('"')) {
68 while (w = stream.next()) {
69 if (w == '"')
70 break;
71
72 if (w == '\\')
73 stream.next();
74 }
75 return 'string';
76 } else if (stream.eat('\'')) {
77 if (stream.match(/\\?.'/))
78 return 'number';
79 } else if (stream.eat('.') || stream.sol() && stream.eat('#')) {
80 state.context = 4;
81
82 if (stream.eatWhile(/\w/))
83 return 'def';
84 } else if (stream.eat('$')) {
85 if (stream.eatWhile(/[\da-f]/i))
86 return 'number';
87 } else if (stream.eat('%')) {
88 if (stream.eatWhile(/[01]/))
89 return 'number';
90 } else {
91 stream.next();
92 }
93 return null;
94 }
95 };
96 });
97
98 CodeMirror.defineMIME("text/x-z80", "z80");
99
100 });
General Comments 0
You need to be logged in to leave comments. Login now