codemirror-rails 3.14 → 3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +178 -94
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +3 -3
  5. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +3 -1
  6. data/vendor/assets/javascripts/codemirror/addons/edit/matchtags.js +51 -0
  7. data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +9 -6
  8. data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +9 -4
  9. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +122 -0
  10. data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +3 -2
  11. data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +24 -17
  12. data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +34 -0
  13. data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +5 -3
  14. data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +7 -3
  15. data/vendor/assets/javascripts/codemirror/addons/hint/pig-hint.js +4 -2
  16. data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +4 -2
  17. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +6 -2
  18. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +5 -2
  19. data/vendor/assets/javascripts/codemirror/addons/lint/coffeescript-lint.js +3 -2
  20. data/vendor/assets/javascripts/codemirror/addons/lint/javascript-lint.js +3 -6
  21. data/vendor/assets/javascripts/codemirror/addons/lint/json-lint.js +3 -2
  22. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +12 -6
  23. data/vendor/assets/javascripts/codemirror/addons/merge/dep/diff_match_patch.js +50 -0
  24. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +40 -24
  25. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +3 -1
  26. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +3 -1
  27. data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +11 -9
  28. data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +1 -1
  29. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +608 -0
  30. data/vendor/assets/javascripts/codemirror/addons/tern/worker.js +39 -0
  31. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +120 -101
  32. data/vendor/assets/javascripts/codemirror/modes/clike.js +2 -1
  33. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +2 -1
  34. data/vendor/assets/javascripts/codemirror/modes/css.js +33 -16
  35. data/vendor/assets/javascripts/codemirror/modes/groovy.js +2 -1
  36. data/vendor/assets/javascripts/codemirror/modes/jade.js +90 -0
  37. data/vendor/assets/javascripts/codemirror/modes/javascript.js +21 -18
  38. data/vendor/assets/javascripts/codemirror/modes/markdown.js +26 -1
  39. data/vendor/assets/javascripts/codemirror/modes/nginx.js +163 -0
  40. data/vendor/assets/javascripts/codemirror/modes/python.js +19 -2
  41. data/vendor/assets/javascripts/codemirror/modes/rst.js +30 -19
  42. data/vendor/assets/javascripts/codemirror/modes/ruby.js +4 -4
  43. data/vendor/assets/javascripts/codemirror/modes/rust.js +2 -1
  44. data/vendor/assets/javascripts/codemirror/modes/scss_test.js +1 -1
  45. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +12 -2
  46. data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +170 -0
  47. data/vendor/assets/javascripts/codemirror/modes/sparql.js +4 -2
  48. data/vendor/assets/javascripts/codemirror/modes/vbscript.js +330 -22
  49. data/vendor/assets/javascripts/codemirror/modes/xml.js +18 -3
  50. data/vendor/assets/stylesheets/codemirror.css +10 -0
  51. data/vendor/assets/stylesheets/codemirror/addons/merge/merge.css +39 -29
  52. data/vendor/assets/stylesheets/codemirror/addons/tern/tern.css +85 -0
  53. data/vendor/assets/stylesheets/codemirror/themes/3024-day.css +33 -0
  54. data/vendor/assets/stylesheets/codemirror/themes/3024-night.css +33 -0
  55. data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +33 -0
  56. data/vendor/assets/stylesheets/codemirror/themes/base16-light.css +33 -0
  57. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +1 -1
  58. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +5 -14
  59. data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-eighties.css +33 -0
  60. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +2 -2
  61. metadata +17 -2
@@ -36,6 +36,12 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
36
36
  var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
37
37
  'keywords': ['nonlocal', 'False', 'True', 'None']};
38
38
 
39
+ if(parserConf.extra_keywords != undefined){
40
+ commonkeywords = commonkeywords.concat(parserConf.extra_keywords);
41
+ }
42
+ if(parserConf.extra_builtins != undefined){
43
+ commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins);
44
+ }
39
45
  if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
40
46
  commonkeywords = commonkeywords.concat(py3.keywords);
41
47
  commonBuiltins = commonBuiltins.concat(py3.builtins);
@@ -318,7 +324,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
318
324
 
319
325
  state.lastToken = style;
320
326
 
321
- if (stream.eol() && stream.lambda) {
327
+ if (stream.eol() && state.lambda) {
322
328
  state.lambda = false;
323
329
  }
324
330
 
@@ -333,9 +339,20 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
333
339
  return state.scopes[0].offset;
334
340
  },
335
341
 
336
- lineComment: "#"
342
+ lineComment: "#",
343
+ fold: "indent"
337
344
  };
338
345
  return external;
339
346
  });
340
347
 
341
348
  CodeMirror.defineMIME("text/x-python", "python");
349
+
350
+ var words = function(str){return str.split(' ');};
351
+
352
+
353
+ CodeMirror.defineMIME("text/x-cython", {
354
+ name: "python",
355
+ extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
356
+ "extern gil include nogil property public"+
357
+ "readonly struct union DEF IF ELIF ELSE")
358
+ });
@@ -36,9 +36,11 @@ CodeMirror.defineMode('rst-base', function (config) {
36
36
  var TAIL = "(?:\\s*|\\W|$)",
37
37
  rx_TAIL = new RegExp(format('^{0}', TAIL));
38
38
 
39
- var NAME = "(?:[^\\W\\d_](?:[\\w\\+\\.\\-:]*[^\\W_])?)",
39
+ var NAME =
40
+ "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",
40
41
  rx_NAME = new RegExp(format('^{0}', NAME));
41
- var NAME_WWS = "(?:[^\\W\\d_](?:[\\w\\s\\+\\.\\-:]*[^\\W_])?)";
42
+ var NAME_WWS =
43
+ "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";
42
44
  var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
43
45
 
44
46
  var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
@@ -480,7 +482,9 @@ CodeMirror.defineMode('rst-base', function (config) {
480
482
  },
481
483
 
482
484
  innerMode: function (state) {
483
- return {state: state.ctx.local, mode: state.ctx.mode};
485
+ return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode}
486
+ : state.ctx ? {state: state.ctx.local, mode: state.ctx.mode}
487
+ : null;
484
488
  },
485
489
 
486
490
  token: function (stream, state) {
@@ -494,6 +498,14 @@ CodeMirror.defineMode('rst-base', function (config) {
494
498
 
495
499
  CodeMirror.defineMode('rst', function (config, options) {
496
500
 
501
+ var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
502
+ var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;
503
+ var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;
504
+
505
+ var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
506
+ var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
507
+ var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
508
+
497
509
  var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
498
510
  var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
499
511
  var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
@@ -501,33 +513,32 @@ CodeMirror.defineMode('rst', function (config, options) {
501
513
  rx_uri_protocol + rx_uri_domain + rx_uri_path
502
514
  );
503
515
 
504
- var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*(\s+|$)/;
505
- var rx_emphasis = /^[^\*]\*[^\*\s](?:[^\*]*[^\*\s])?\*(\s+|$)/;
506
- var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``(\s+|$)/;
507
-
508
- var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
509
- var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
510
- var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
511
-
512
516
  var overlay = {
513
517
  token: function (stream) {
514
518
 
515
- if (stream.match(rx_uri)) return 'link';
516
- if (stream.match(rx_strong)) return 'strong';
517
- if (stream.match(rx_emphasis)) return 'em';
518
- if (stream.match(rx_literal)) return 'string-2';
519
- if (stream.match(rx_number)) return 'number';
520
- if (stream.match(rx_positive)) return 'positive';
521
- if (stream.match(rx_negative)) return 'negative';
519
+ if (stream.match(rx_strong) && stream.match (/\W+|$/, false))
520
+ return 'strong';
521
+ if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))
522
+ return 'em';
523
+ if (stream.match(rx_literal) && stream.match (/\W+|$/, false))
524
+ return 'string-2';
525
+ if (stream.match(rx_number))
526
+ return 'number';
527
+ if (stream.match(rx_positive))
528
+ return 'positive';
529
+ if (stream.match(rx_negative))
530
+ return 'negative';
531
+ if (stream.match(rx_uri))
532
+ return 'link';
522
533
 
523
534
  while (stream.next() != null) {
524
- if (stream.match(rx_uri, false)) break;
525
535
  if (stream.match(rx_strong, false)) break;
526
536
  if (stream.match(rx_emphasis, false)) break;
527
537
  if (stream.match(rx_literal, false)) break;
528
538
  if (stream.match(rx_number, false)) break;
529
539
  if (stream.match(rx_positive, false)) break;
530
540
  if (stream.match(rx_negative, false)) break;
541
+ if (stream.match(rx_uri, false)) break;
531
542
  }
532
543
 
533
544
  return null;
@@ -36,11 +36,11 @@ CodeMirror.defineMode("ruby", function(config) {
36
36
  } else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
37
37
  return chain(readQuoted(ch, "string-2", true), stream, state);
38
38
  } else if (ch == "%") {
39
- var style = "string", embed = false;
39
+ var style = "string", embed = true;
40
40
  if (stream.eat("s")) style = "atom";
41
- else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
42
- else if (stream.eat(/[r]/)) { style = "string-2"; embed = true; }
43
- else if (stream.eat(/[wxq]/)) style = "string";
41
+ else if (stream.eat(/[WQ]/)) style = "string";
42
+ else if (stream.eat(/[r]/)) style = "string-2";
43
+ else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
44
44
  var delim = stream.eat(/[^\w\s]/);
45
45
  if (!delim) return "operator";
46
46
  if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
@@ -428,7 +428,8 @@ CodeMirror.defineMode("rust", function() {
428
428
  electricChars: "{}",
429
429
  blockCommentStart: "/*",
430
430
  blockCommentEnd: "*/",
431
- lineComment: "//"
431
+ lineComment: "//",
432
+ fold: "brace"
432
433
  };
433
434
  });
434
435
 
@@ -64,7 +64,7 @@
64
64
  "[tag p] { [tag a] { [property color][operator :][atom #000]; } }");
65
65
 
66
66
  MT('interpolation_in_property',
67
- "[tag foo] { [operator #{][variable-2 $hello][operator }:][atom #000]; }");
67
+ "[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }");
68
68
 
69
69
  MT('interpolation_in_selector',
70
70
  "[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");
@@ -36,8 +36,13 @@ CodeMirror.defineMode('smalltalk', function(config) {
36
36
  token = nextString(stream, new Context(nextString, context));
37
37
 
38
38
  } else if (aChar === '#') {
39
- stream.eatWhile(/[^ .\[\]()]/);
40
- token.name = 'string-2';
39
+ if (stream.peek() === '\'') {
40
+ stream.next();
41
+ token = nextSymbol(stream, new Context(nextSymbol, context));
42
+ } else {
43
+ stream.eatWhile(/[^ .\[\]()]/);
44
+ token.name = 'string-2';
45
+ }
41
46
 
42
47
  } else if (aChar === '$') {
43
48
  if (stream.next() === '<') {
@@ -89,6 +94,11 @@ CodeMirror.defineMode('smalltalk', function(config) {
89
94
  return new Token('string', stream.eat('\'') ? context.parent : context, false);
90
95
  };
91
96
 
97
+ var nextSymbol = function(stream, context) {
98
+ stream.eatWhile(/[^']/);
99
+ return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
100
+ };
101
+
92
102
  var nextTemporaries = function(stream, context) {
93
103
  var token = new Token(null, context, false);
94
104
  var aChar = stream.next();
@@ -0,0 +1,170 @@
1
+ /**
2
+ * @file smartymixed.js
3
+ * @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
4
+ * @author Ruslan Osmanov <rrosmanov at gmail dot com>
5
+ * @version 3.0
6
+ * @date 05.07.2013
7
+ */
8
+ CodeMirror.defineMode("smartymixed", function(config) {
9
+ var settings, regs, helpers, parsers,
10
+ htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
11
+ smartyMode = CodeMirror.getMode(config, "smarty"),
12
+
13
+ settings = {
14
+ rightDelimiter: '}',
15
+ leftDelimiter: '{'
16
+ };
17
+
18
+ if (config.hasOwnProperty("leftDelimiter")) {
19
+ settings.leftDelimiter = config.leftDelimiter;
20
+ }
21
+ if (config.hasOwnProperty("rightDelimiter")) {
22
+ settings.rightDelimiter = config.rightDelimiter;
23
+ }
24
+
25
+ regs = {
26
+ smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"),
27
+ literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter),
28
+ literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter),
29
+ hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter),
30
+ htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter)
31
+ };
32
+
33
+ helpers = {
34
+ chain: function(stream, state, parser) {
35
+ state.tokenize = parser;
36
+ return parser(stream, state);
37
+ },
38
+
39
+ cleanChain: function(stream, state, parser) {
40
+ state.tokenize = null;
41
+ state.localState = null;
42
+ state.localMode = null;
43
+ return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
44
+ },
45
+
46
+ maybeBackup: function(stream, pat, style) {
47
+ var cur = stream.current();
48
+ var close = cur.search(pat),
49
+ m;
50
+ if (close > - 1) stream.backUp(cur.length - close);
51
+ else if (m = cur.match(/<\/?$/)) {
52
+ stream.backUp(cur.length);
53
+ if (!stream.match(pat, false)) stream.match(cur[0]);
54
+ }
55
+ return style;
56
+ }
57
+ };
58
+
59
+ parsers = {
60
+ html: function(stream, state) {
61
+ if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false)) {
62
+ state.tokenize = parsers.smarty;
63
+ state.localMode = smartyMode;
64
+ state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
65
+ return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
66
+ }
67
+ return htmlMixedMode.token(stream, state.htmlMixedState);
68
+ },
69
+
70
+ smarty: function(stream, state) {
71
+ if (stream.match(settings.leftDelimiter, false)) {
72
+ if (stream.match(regs.smartyComment, false)) {
73
+ return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
74
+ }
75
+ } else if (stream.match(settings.rightDelimiter, false)) {
76
+ stream.eat(settings.rightDelimiter);
77
+ state.tokenize = parsers.html;
78
+ state.localMode = htmlMixedMode;
79
+ state.localState = state.htmlMixedState;
80
+ return "tag";
81
+ }
82
+
83
+ return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
84
+ },
85
+
86
+ inBlock: function(style, terminator) {
87
+ return function(stream, state) {
88
+ while (!stream.eol()) {
89
+ if (stream.match(terminator)) {
90
+ helpers.cleanChain(stream, state, "");
91
+ break;
92
+ }
93
+ stream.next();
94
+ }
95
+ return style;
96
+ };
97
+ }
98
+ };
99
+
100
+ return {
101
+ startState: function() {
102
+ var state = htmlMixedMode.startState();
103
+ return {
104
+ token: parsers.html,
105
+ localMode: null,
106
+ localState: null,
107
+ htmlMixedState: state,
108
+ tokenize: null,
109
+ inLiteral: false
110
+ };
111
+ },
112
+
113
+ copyState: function(state) {
114
+ var local = null, tok = (state.tokenize || state.token);
115
+ if (state.localState) {
116
+ local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
117
+ }
118
+ return {
119
+ token: state.token,
120
+ tokenize: state.tokenize,
121
+ localMode: state.localMode,
122
+ localState: local,
123
+ htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
124
+ inLiteral: state.inLiteral
125
+ };
126
+ },
127
+
128
+ token: function(stream, state) {
129
+ if (stream.match(settings.leftDelimiter, false)) {
130
+ if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
131
+ state.inLiteral = true;
132
+ return "keyword";
133
+ } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
134
+ state.inLiteral = false;
135
+ return "keyword";
136
+ }
137
+ }
138
+ if (state.inLiteral && state.localState != state.htmlMixedState) {
139
+ state.tokenize = parsers.html;
140
+ state.localMode = htmlMixedMode;
141
+ state.localState = state.htmlMixedState;
142
+ }
143
+
144
+ var style = (state.tokenize || state.token)(stream, state);
145
+ return style;
146
+ },
147
+
148
+ indent: function(state, textAfter) {
149
+ if (state.localMode == smartyMode
150
+ || (state.inLiteral && !state.localMode)
151
+ || regs.hasLeftDelimeter.test(textAfter)) {
152
+ return CodeMirror.Pass;
153
+ }
154
+ return htmlMixedMode.indent(state.htmlMixedState, textAfter);
155
+ },
156
+
157
+ electricChars: "/{}:",
158
+
159
+ innerMode: function(state) {
160
+ return {
161
+ state: state.localState || state.htmlMixedState,
162
+ mode: state.localMode || htmlMixedMode
163
+ };
164
+ }
165
+ };
166
+ },
167
+ "htmlmixed");
168
+
169
+ CodeMirror.defineMIME("text/x-smarty", "smartymixed");
170
+ // vim: et ts=2 sts=2 sw=2
@@ -6,10 +6,12 @@ CodeMirror.defineMode("sparql", function(config) {
6
6
  return new RegExp("^(?:" + words.join("|") + ")$", "i");
7
7
  }
8
8
  var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
9
- "isblank", "isliteral", "union", "a"]);
9
+ "isblank", "isliteral", "a"]);
10
10
  var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
11
11
  "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
12
- "graph", "by", "asc", "desc"]);
12
+ "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
13
+ "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
14
+ "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
13
15
  var operatorChars = /[*+\-<>=&|]/;
14
16
 
15
17
  function tokenBase(stream, state) {
@@ -1,26 +1,334 @@
1
- CodeMirror.defineMode("vbscript", function() {
2
- var regexVBScriptKeyword = /^(?:Call|Case|CDate|Clear|CInt|CLng|Const|CStr|Description|Dim|Do|Each|Else|ElseIf|End|Err|Error|Exit|False|For|Function|If|LCase|Loop|LTrim|Next|Nothing|Now|Number|On|Preserve|Quit|ReDim|Resume|RTrim|Select|Set|Sub|Then|To|Trim|True|UBound|UCase|Until|VbCr|VbCrLf|VbLf|VbTab)$/im;
3
-
4
- return {
5
- token: function(stream) {
6
- if (stream.eatSpace()) return null;
7
- var ch = stream.next();
8
- if (ch == "'") {
9
- stream.skipToEnd();
10
- return "comment";
11
- }
12
- if (ch == '"') {
13
- stream.skipTo('"');
14
- return "string";
15
- }
16
-
17
- if (/\w/.test(ch)) {
18
- stream.eatWhile(/\w/);
19
- if (regexVBScriptKeyword.test(stream.current())) return "keyword";
20
- }
21
- return null;
1
+ /*
2
+ For extra ASP classic objects, initialize CodeMirror instance with this option:
3
+ isASP: true
4
+
5
+ E.G.:
6
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
7
+ lineNumbers: true,
8
+ isASP: true
9
+ });
10
+ */
11
+ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
12
+ var ERRORCLASS = 'error';
13
+
14
+ function wordRegexp(words) {
15
+ return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
16
+ }
17
+
18
+ var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
19
+ var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
20
+ var singleDelimiters = new RegExp('^[\\.,]');
21
+ var brakets = new RegExp('^[\\(\\)]');
22
+ var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
23
+
24
+ var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
25
+ var middleKeywords = ['else','elseif','case'];
26
+ var endKeywords = ['next','loop','wend'];
27
+
28
+ var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']);
29
+ var commonkeywords = ['dim', 'redim', 'then', 'until', 'randomize',
30
+ 'byval','byref','new','property', 'exit', 'in',
31
+ 'const','private', 'public',
32
+ 'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me'];
33
+
34
+ //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx
35
+ var atomWords = ['true', 'false', 'nothing', 'empty', 'null'];
36
+ //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx
37
+ var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart',
38
+ 'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject',
39
+ 'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left',
40
+ 'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round',
41
+ 'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp',
42
+ 'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year'];
43
+
44
+ //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx
45
+ var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare',
46
+ 'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek',
47
+ 'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError',
48
+ 'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2',
49
+ 'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo',
50
+ 'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse',
51
+ 'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray'];
52
+ //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx
53
+ var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp'];
54
+ var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count'];
55
+ var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit'];
56
+
57
+ var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application'];
58
+ var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response
59
+ 'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request
60
+ 'contents', 'staticobjects', //application
61
+ 'codepage', 'lcid', 'sessionid', 'timeout', //session
62
+ 'scripttimeout']; //server
63
+ var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response
64
+ 'binaryread', //request
65
+ 'remove', 'removeall', 'lock', 'unlock', //application
66
+ 'abandon', //session
67
+ 'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server
68
+
69
+ var knownWords = knownMethods.concat(knownProperties);
70
+
71
+ builtinObjsWords = builtinObjsWords.concat(builtinConsts);
72
+
73
+ if (conf.isASP){
74
+ builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords);
75
+ knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties);
76
+ };
77
+
78
+ var keywords = wordRegexp(commonkeywords);
79
+ var atoms = wordRegexp(atomWords);
80
+ var builtinFuncs = wordRegexp(builtinFuncsWords);
81
+ var builtinObjs = wordRegexp(builtinObjsWords);
82
+ var known = wordRegexp(knownWords);
83
+ var stringPrefixes = '"';
84
+
85
+ var opening = wordRegexp(openingKeywords);
86
+ var middle = wordRegexp(middleKeywords);
87
+ var closing = wordRegexp(endKeywords);
88
+ var doubleClosing = wordRegexp(['end']);
89
+ var doOpening = wordRegexp(['do']);
90
+ var noIndentWords = wordRegexp(['on error resume next', 'exit']);
91
+ var comment = wordRegexp(['rem']);
92
+
93
+
94
+ function indent(_stream, state) {
95
+ state.currentIndent++;
96
+ }
97
+
98
+ function dedent(_stream, state) {
99
+ state.currentIndent--;
100
+ }
101
+ // tokenizers
102
+ function tokenBase(stream, state) {
103
+ if (stream.eatSpace()) {
104
+ return 'space';
105
+ //return null;
106
+ }
107
+
108
+ var ch = stream.peek();
109
+
110
+ // Handle Comments
111
+ if (ch === "'") {
112
+ stream.skipToEnd();
113
+ return 'comment';
114
+ }
115
+ if (stream.match(comment)){
116
+ stream.skipToEnd();
117
+ return 'comment';
118
+ }
119
+
120
+
121
+ // Handle Number Literals
122
+ if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) {
123
+ var floatLiteral = false;
124
+ // Floats
125
+ if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; }
126
+ else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
127
+ else if (stream.match(/^\.\d+/)) { floatLiteral = true; }
128
+
129
+ if (floatLiteral) {
130
+ // Float literals may be "imaginary"
131
+ stream.eat(/J/i);
132
+ return 'number';
133
+ }
134
+ // Integers
135
+ var intLiteral = false;
136
+ // Hex
137
+ if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
138
+ // Octal
139
+ else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
140
+ // Decimal
141
+ else if (stream.match(/^[1-9]\d*F?/)) {
142
+ // Decimal literals may be "imaginary"
143
+ stream.eat(/J/i);
144
+ // TODO - Can you have imaginary longs?
145
+ intLiteral = true;
146
+ }
147
+ // Zero by itself with no other piece of number.
148
+ else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
149
+ if (intLiteral) {
150
+ // Integer literals may be "long"
151
+ stream.eat(/L/i);
152
+ return 'number';
153
+ }
154
+ }
155
+
156
+ // Handle Strings
157
+ if (stream.match(stringPrefixes)) {
158
+ state.tokenize = tokenStringFactory(stream.current());
159
+ return state.tokenize(stream, state);
160
+ }
161
+
162
+ // Handle operators and Delimiters
163
+ if (stream.match(doubleOperators)
164
+ || stream.match(singleOperators)
165
+ || stream.match(wordOperators)) {
166
+ return 'operator';
167
+ }
168
+ if (stream.match(singleDelimiters)) {
169
+ return null;
170
+ }
171
+
172
+ if (stream.match(brakets)) {
173
+ return "bracket";
174
+ }
175
+
176
+ if (stream.match(noIndentWords)) {
177
+ state.doInCurrentLine = true;
178
+
179
+ return 'keyword';
180
+ }
181
+
182
+ if (stream.match(doOpening)) {
183
+ indent(stream,state);
184
+ state.doInCurrentLine = true;
185
+
186
+ return 'keyword';
187
+ }
188
+ if (stream.match(opening)) {
189
+ if (! state.doInCurrentLine)
190
+ indent(stream,state);
191
+ else
192
+ state.doInCurrentLine = false;
193
+
194
+ return 'keyword';
195
+ }
196
+ if (stream.match(middle)) {
197
+ return 'keyword';
198
+ }
199
+
200
+
201
+ if (stream.match(doubleClosing)) {
202
+ dedent(stream,state);
203
+ dedent(stream,state);
204
+
205
+ return 'keyword';
206
+ }
207
+ if (stream.match(closing)) {
208
+ if (! state.doInCurrentLine)
209
+ dedent(stream,state);
210
+ else
211
+ state.doInCurrentLine = false;
212
+
213
+ return 'keyword';
214
+ }
215
+
216
+ if (stream.match(keywords)) {
217
+ return 'keyword';
218
+ }
219
+
220
+ if (stream.match(atoms)) {
221
+ return 'atom';
222
+ }
223
+
224
+ if (stream.match(known)) {
225
+ return 'variable-2';
226
+ }
227
+
228
+ if (stream.match(builtinFuncs)) {
229
+ return 'builtin';
230
+ }
231
+
232
+ if (stream.match(builtinObjs)){
233
+ return 'variable-2';
234
+ }
235
+
236
+ if (stream.match(identifiers)) {
237
+ return 'variable';
238
+ }
239
+
240
+ // Handle non-detected items
241
+ stream.next();
242
+ return ERRORCLASS;
22
243
  }
23
- };
244
+
245
+ function tokenStringFactory(delimiter) {
246
+ var singleline = delimiter.length == 1;
247
+ var OUTCLASS = 'string';
248
+
249
+ return function(stream, state) {
250
+ while (!stream.eol()) {
251
+ stream.eatWhile(/[^'"]/);
252
+ if (stream.match(delimiter)) {
253
+ state.tokenize = tokenBase;
254
+ return OUTCLASS;
255
+ } else {
256
+ stream.eat(/['"]/);
257
+ }
258
+ }
259
+ if (singleline) {
260
+ if (parserConf.singleLineStringErrors) {
261
+ return ERRORCLASS;
262
+ } else {
263
+ state.tokenize = tokenBase;
264
+ }
265
+ }
266
+ return OUTCLASS;
267
+ };
268
+ }
269
+
270
+
271
+ function tokenLexer(stream, state) {
272
+ var style = state.tokenize(stream, state);
273
+ var current = stream.current();
274
+
275
+ // Handle '.' connected identifiers
276
+ if (current === '.') {
277
+ style = state.tokenize(stream, state);
278
+
279
+ current = stream.current();
280
+ if (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword'){//|| knownWords.indexOf(current.substring(1)) > -1) {
281
+ if (style === 'builtin' || style === 'keyword') style='variable';
282
+ if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2';
283
+
284
+ return style;
285
+ } else {
286
+ return ERRORCLASS;
287
+ }
288
+ }
289
+
290
+ return style;
291
+ }
292
+
293
+ var external = {
294
+ electricChars:"dDpPtTfFeE ",
295
+ startState: function() {
296
+ return {
297
+ tokenize: tokenBase,
298
+ lastToken: null,
299
+ currentIndent: 0,
300
+ nextLineIndent: 0,
301
+ doInCurrentLine: false,
302
+ ignoreKeyword: false
303
+
304
+
305
+ };
306
+ },
307
+
308
+ token: function(stream, state) {
309
+ if (stream.sol()) {
310
+ state.currentIndent += state.nextLineIndent;
311
+ state.nextLineIndent = 0;
312
+ state.doInCurrentLine = 0;
313
+ }
314
+ var style = tokenLexer(stream, state);
315
+
316
+ state.lastToken = {style:style, content: stream.current()};
317
+
318
+ if (style==='space') style=null;
319
+
320
+ return style;
321
+ },
322
+
323
+ indent: function(state, textAfter) {
324
+ var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
325
+ if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
326
+ if(state.currentIndent < 0) return 0;
327
+ return state.currentIndent * conf.indentUnit;
328
+ }
329
+
330
+ };
331
+ return external;
24
332
  });
25
333
 
26
334
  CodeMirror.defineMIME("text/vbscript", "vbscript");