codemirror-rails 4.0 → 4.1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +302 -115
  4. data/vendor/assets/javascripts/codemirror/addons/display/rulers.js +2 -2
  5. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +35 -18
  6. data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +18 -9
  7. data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +1 -1
  8. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +3 -1
  9. data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +31 -13
  10. data/vendor/assets/javascripts/codemirror/addons/lint/css-lint.js +1 -0
  11. data/vendor/assets/javascripts/codemirror/addons/lint/javascript-lint.js +1 -0
  12. data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +15 -10
  13. data/vendor/assets/javascripts/codemirror/addons/mode/overlay.js +8 -2
  14. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +1 -0
  15. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -0
  16. data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +1 -0
  17. data/vendor/assets/javascripts/codemirror/addons/search/search.js +14 -14
  18. data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +14 -2
  19. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +212 -141
  20. data/vendor/assets/javascripts/codemirror/modes/clike.js +4 -5
  21. data/vendor/assets/javascripts/codemirror/modes/css.js +23 -6
  22. data/vendor/assets/javascripts/codemirror/modes/django.js +64 -0
  23. data/vendor/assets/javascripts/codemirror/modes/dylan.js +284 -0
  24. data/vendor/assets/javascripts/codemirror/modes/erlang.js +1 -1
  25. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -0
  26. data/vendor/assets/javascripts/codemirror/modes/haml.js +3 -8
  27. data/vendor/assets/javascripts/codemirror/modes/haxe.js +75 -3
  28. data/vendor/assets/javascripts/codemirror/modes/javascript.js +14 -8
  29. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +111 -35
  30. data/vendor/assets/javascripts/codemirror/modes/livescript.js +4 -4
  31. data/vendor/assets/javascripts/codemirror/modes/markdown.js +5 -2
  32. data/vendor/assets/javascripts/codemirror/modes/php.js +99 -9
  33. data/vendor/assets/javascripts/codemirror/modes/r.js +3 -1
  34. data/vendor/assets/javascripts/codemirror/modes/verilog.js +237 -78
  35. data/vendor/assets/javascripts/codemirror/modes/xml.js +61 -29
  36. data/vendor/assets/stylesheets/codemirror.css +5 -3
  37. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +0 -1
  38. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +0 -4
  39. data/vendor/assets/stylesheets/codemirror/themes/mdn-like.css +1 -1
  40. data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +0 -1
  41. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +0 -2
  42. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +3 -17
  43. metadata +20 -18
@@ -31,7 +31,7 @@
31
31
  var val = cm.getOption("rulers");
32
32
  var cw = cm.defaultCharWidth();
33
33
  var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
34
- var bot = -cm.display.scroller.offsetHeight;
34
+ var minH = cm.display.scroller.offsetHeight + 30;
35
35
  for (var i = 0; i < val.length; i++) {
36
36
  var elt = document.createElement("div");
37
37
  var col, cls = null;
@@ -42,7 +42,7 @@
42
42
  cls = val[i].className;
43
43
  }
44
44
  elt.className = "CodeMirror-ruler" + (cls ? " " + cls : "");
45
- elt.style.cssText = "left: " + (left + col * cw) + "px; top: -50px; bottom: " + bot + "px";
45
+ elt.style.cssText = "left: " + (left + col * cw) + "px; top: -50px; bottom: -20px; min-height: " + minH + "px";
46
46
  cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv);
47
47
  }
48
48
  }
@@ -10,6 +10,8 @@
10
10
  var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
11
11
  var SPACE_CHAR_REGEX = /\s/;
12
12
 
13
+ var Pos = CodeMirror.Pos;
14
+
13
15
  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
14
16
  if (old != CodeMirror.Init && old)
15
17
  cm.removeKeyMap("autoCloseBrackets");
@@ -26,8 +28,8 @@
26
28
  });
27
29
 
28
30
  function charsAround(cm, pos) {
29
- var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1),
30
- CodeMirror.Pos(pos.line, pos.ch + 1));
31
+ var str = cm.getRange(Pos(pos.line, pos.ch - 1),
32
+ Pos(pos.line, pos.ch + 1));
31
33
  return str.length == 2 ? str : null;
32
34
  }
33
35
 
@@ -44,7 +46,7 @@
44
46
  }
45
47
  for (var i = ranges.length - 1; i >= 0; i--) {
46
48
  var cur = ranges[i].head;
47
- cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
49
+ cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
48
50
  }
49
51
  }
50
52
  };
@@ -58,11 +60,18 @@
58
60
  var range = ranges[i], cur = range.head, curType;
59
61
  if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
60
62
  return CodeMirror.Pass;
61
- var next = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
63
+ var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
62
64
  if (!range.empty())
63
65
  curType = "surround";
64
- else if (left == right && next == right)
65
- curType = "skip";
66
+ else if (left == right && next == right) {
67
+ if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
68
+ curType = "skipThree";
69
+ else
70
+ curType = "skip";
71
+ } else if (left == right && cur.ch > 1 &&
72
+ cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
73
+ (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left))
74
+ curType = "addFour";
66
75
  else if (left == right && CodeMirror.isWordChar(next))
67
76
  return CodeMirror.Pass;
68
77
  else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
@@ -73,24 +82,32 @@
73
82
  else if (type != curType) return CodeMirror.Pass;
74
83
  }
75
84
 
76
- if (type == "skip") {
77
- cm.execCommand("goCharRight");
78
- } else if (type == "surround") {
79
- var sels = cm.getSelections();
80
- for (var i = 0; i < sels.length; i++)
81
- sels[i] = left + sels[i] + right;
82
- cm.replaceSelections(sels, "around");
83
- } else if (type == "both") {
84
- cm.replaceSelection(left + right, null);
85
- cm.execCommand("goCharLeft");
86
- }
85
+ cm.operation(function() {
86
+ if (type == "skip") {
87
+ cm.execCommand("goCharRight");
88
+ } else if (type == "skipThree") {
89
+ for (var i = 0; i < 3; i++)
90
+ cm.execCommand("goCharRight");
91
+ } else if (type == "surround") {
92
+ var sels = cm.getSelections();
93
+ for (var i = 0; i < sels.length; i++)
94
+ sels[i] = left + sels[i] + right;
95
+ cm.replaceSelections(sels, "around");
96
+ } else if (type == "both") {
97
+ cm.replaceSelection(left + right, null);
98
+ cm.execCommand("goCharLeft");
99
+ } else if (type == "addFour") {
100
+ cm.replaceSelection(left + left + left + left, "before");
101
+ cm.execCommand("goCharRight");
102
+ }
103
+ });
87
104
  };
88
105
  if (left != right) map["'" + right + "'"] = function(cm) {
89
106
  var ranges = cm.listSelections();
90
107
  for (var i = 0; i < ranges.length; i++) {
91
108
  var range = ranges[i];
92
109
  if (!range.empty() ||
93
- cm.getRange(range.head, CodeMirror.Pos(range.head.line, range.head.ch + 1)) != right)
110
+ cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
94
111
  return CodeMirror.Pass;
95
112
  }
96
113
  cm.execCommand("goCharRight");
@@ -22,15 +22,24 @@
22
22
  var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
23
23
 
24
24
  var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
25
+ if (found == null) return null;
25
26
  return {from: Pos(where.line, pos), to: found && found.pos,
26
27
  match: found && found.ch == match.charAt(0), forward: dir > 0};
27
28
  }
28
29
 
30
+ // bracketRegex is used to specify which type of bracket to scan
31
+ // should be a regexp, e.g. /[[\]]/
32
+ //
33
+ // Note: If "where" is on an open bracket, then this bracket is ignored.
34
+ //
35
+ // Returns false when no bracket was found, null when it reached
36
+ // maxScanLines and gave up
29
37
  function scanForBracket(cm, where, dir, style, config) {
30
38
  var maxScanLen = (config && config.maxScanLineLength) || 10000;
31
- var maxScanLines = (config && config.maxScanLines) || 500;
39
+ var maxScanLines = (config && config.maxScanLines) || 1000;
32
40
 
33
- var stack = [], re = /[(){}[\]]/;
41
+ var stack = [];
42
+ var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
34
43
  var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
35
44
  : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
36
45
  for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
@@ -49,6 +58,7 @@
49
58
  }
50
59
  }
51
60
  }
61
+ return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
52
62
  }
53
63
 
54
64
  function matchBrackets(cm, autoclear, config) {
@@ -57,11 +67,10 @@
57
67
  var marks = [], ranges = cm.listSelections();
58
68
  for (var i = 0; i < ranges.length; i++) {
59
69
  var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
60
- if (match && cm.getLine(match.from.line).length <= maxHighlightLen &&
61
- match.to && cm.getLine(match.to.line).length <= maxHighlightLen) {
70
+ if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
62
71
  var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
63
72
  marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
64
- if (match.to)
73
+ if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
65
74
  marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
66
75
  }
67
76
  }
@@ -99,10 +108,10 @@
99
108
  });
100
109
 
101
110
  CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
102
- CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){
103
- return findMatchingBracket(this, pos, strict);
111
+ CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
112
+ return findMatchingBracket(this, pos, strict, config);
104
113
  });
105
- CodeMirror.defineExtension("scanForBracket", function(pos, dir, style){
106
- return scanForBracket(this, pos, dir, style);
114
+ CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
115
+ return scanForBracket(this, pos, dir, style, config);
107
116
  });
108
117
  });
@@ -31,7 +31,7 @@
31
31
  result.push(name);
32
32
  }
33
33
 
34
- var st = token.state.state;
34
+ var st = inner.state.state;
35
35
  if (st == "pseudo" || token.type == "variable-3") {
36
36
  add(pseudoClasses);
37
37
  } else if (st == "block" || st == "maybeprop") {
@@ -53,7 +53,8 @@
53
53
  pick: function(data, i) {
54
54
  var completion = data.list[i];
55
55
  if (completion.hint) completion.hint(this.cm, data, completion);
56
- else this.cm.replaceRange(getText(completion), completion.from||data.from, completion.to||data.to);
56
+ else this.cm.replaceRange(getText(completion), completion.from || data.from,
57
+ completion.to || data.to, "complete");
57
58
  CodeMirror.signal(data, "pick", completion);
58
59
  this.close();
59
60
  },
@@ -100,6 +101,7 @@
100
101
  data = data_;
101
102
  if (finished) return;
102
103
  if (!data || !data.list.length) return done();
104
+ if (completion.widget) completion.widget.close();
103
105
  completion.widget = new Widget(completion, data);
104
106
  }
105
107
 
@@ -18,27 +18,45 @@
18
18
  var inner = CodeMirror.innerMode(cm.getMode(), token.state);
19
19
  if (inner.mode.name != "xml") return;
20
20
  var result = [], replaceToken = false, prefix;
21
- var isTag = token.string.charAt(0) == "<";
22
- if (!inner.state.tagName || isTag) { // Tag completion
23
- if (isTag) {
24
- prefix = token.string.slice(1);
25
- replaceToken = true;
26
- }
21
+ var tag = /\btag\b/.test(token.type), tagName = tag && /^\w/.test(token.string), tagStart;
22
+ if (tagName) {
23
+ var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start);
24
+ var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null;
25
+ if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1);
26
+ } else if (tag && token.string == "<") {
27
+ tagType = "open";
28
+ } else if (tag && token.string == "</") {
29
+ tagType = "close";
30
+ }
31
+ if (!tag && !inner.state.tagName || tagType) {
32
+ if (tagName)
33
+ prefix = token.string;
34
+ replaceToken = tagType;
27
35
  var cx = inner.state.context, curTag = cx && tags[cx.tagName];
28
36
  var childList = cx ? curTag && curTag.children : tags["!top"];
29
- if (childList) {
37
+ if (childList && tagType != "close") {
30
38
  for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
31
39
  result.push("<" + childList[i]);
32
- } else {
33
- for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
34
- result.push("<" + name);
40
+ } else if (tagType != "close") {
41
+ for (var name in tags)
42
+ if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
43
+ result.push("<" + name);
35
44
  }
36
- if (cx && (!prefix || ("/" + cx.tagName).lastIndexOf(prefix, 0) == 0))
45
+ if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0))
37
46
  result.push("</" + cx.tagName + ">");
38
47
  } else {
39
48
  // Attribute completion
40
49
  var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
41
- if (!attrs) return;
50
+ var globalAttrs = tags["!attrs"];
51
+ if (!attrs && !globalAttrs) return;
52
+ if (!attrs) {
53
+ attrs = globalAttrs;
54
+ } else if (globalAttrs) { // Combine tag-local and global attributes
55
+ var set = {};
56
+ for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
57
+ for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
58
+ attrs = set;
59
+ }
42
60
  if (token.type == "string" || token.string == "=") { // A value
43
61
  var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
44
62
  Pos(cur.line, token.type == "string" ? token.start : token.end));
@@ -66,7 +84,7 @@
66
84
  }
67
85
  return {
68
86
  list: result,
69
- from: replaceToken ? Pos(cur.line, token.start) : cur,
87
+ from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
70
88
  to: replaceToken ? Pos(cur.line, token.end) : cur
71
89
  };
72
90
  }
@@ -14,6 +14,7 @@
14
14
 
15
15
  CodeMirror.registerHelper("lint", "css", function(text) {
16
16
  var found = [];
17
+ if (!window.CSSLint) return found;
17
18
  var results = CSSLint.verify(text), messages = results.messages, message = null;
18
19
  for ( var i = 0; i < messages.length; i++) {
19
20
  message = messages[i];
@@ -19,6 +19,7 @@
19
19
  "Unclosed string", "Stopping, unable to continue" ];
20
20
 
21
21
  function validator(text, options) {
22
+ if (!window.JSHINT) return [];
22
23
  JSHINT(text, options);
23
24
  var errors = JSHINT.data().errors, result = [];
24
25
  if (errors) parseErrors(errors, result);
@@ -53,6 +53,14 @@
53
53
  }
54
54
  };
55
55
 
56
+ function ensureDiff(dv) {
57
+ if (dv.diffOutOfDate) {
58
+ dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
59
+ dv.diffOutOfDate = false;
60
+ CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
61
+ }
62
+ }
63
+
56
64
  function registerUpdate(dv) {
57
65
  var edit = {from: 0, to: 0, marked: []};
58
66
  var orig = {from: 0, to: 0, marked: []};
@@ -65,11 +73,7 @@
65
73
  clearMarks(dv.orig, orig.marked, dv.classes);
66
74
  edit.from = edit.to = orig.from = orig.to = 0;
67
75
  }
68
- if (dv.diffOutOfDate) {
69
- dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
70
- dv.diffOutOfDate = false;
71
- CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
72
- }
76
+ ensureDiff(dv);
73
77
  if (dv.showDifferences) {
74
78
  updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
75
79
  updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
@@ -165,7 +169,7 @@
165
169
  var mark = arr[i];
166
170
  if (mark instanceof CodeMirror.TextMarker) {
167
171
  mark.clear();
168
- } else {
172
+ } else if (mark.parent) {
169
173
  editor.removeLineClass(mark, "background", classes.chunk);
170
174
  editor.removeLineClass(mark, "background", classes.start);
171
175
  editor.removeLineClass(mark, "background", classes.end);
@@ -362,10 +366,10 @@
362
366
  if (this.left) this.left.setShowDifferences(val);
363
367
  },
364
368
  rightChunks: function() {
365
- return this.right && getChunks(this.right.diff);
369
+ return this.right && getChunks(this.right);
366
370
  },
367
371
  leftChunks: function() {
368
- return this.left && getChunks(this.left.diff);
372
+ return this.left && getChunks(this.left);
369
373
  }
370
374
  };
371
375
 
@@ -416,9 +420,10 @@
416
420
  f(startOrig, orig.line + 1, startEdit, edit.line + 1);
417
421
  }
418
422
 
419
- function getChunks(diff) {
423
+ function getChunks(dv) {
424
+ ensureDiff(dv);
420
425
  var collect = [];
421
- iterateChunks(diff, function(topOrig, botOrig, topEdit, botEdit) {
426
+ iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
422
427
  collect.push({origFrom: topOrig, origTo: botOrig,
423
428
  editFrom: topEdit, editTo: botEdit});
424
429
  });
@@ -23,7 +23,8 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
23
23
  base: CodeMirror.startState(base),
24
24
  overlay: CodeMirror.startState(overlay),
25
25
  basePos: 0, baseCur: null,
26
- overlayPos: 0, overlayCur: null
26
+ overlayPos: 0, overlayCur: null,
27
+ lineSeen: null
27
28
  };
28
29
  },
29
30
  copyState: function(state) {
@@ -36,6 +37,12 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
36
37
  },
37
38
 
38
39
  token: function(stream, state) {
40
+ if (stream.sol() || stream.string != state.lineSeen ||
41
+ Math.min(state.basePos, state.overlayPos) < stream.start) {
42
+ state.lineSeen = stream.string;
43
+ state.basePos = state.overlayPos = stream.start;
44
+ }
45
+
39
46
  if (stream.start == state.basePos) {
40
47
  state.baseCur = base.token(stream, state.base);
41
48
  state.basePos = stream.pos;
@@ -46,7 +53,6 @@ CodeMirror.overlayMode = function(base, overlay, combine) {
46
53
  state.overlayPos = stream.pos;
47
54
  }
48
55
  stream.pos = Math.min(state.basePos, state.overlayPos);
49
- if (stream.eol()) state.basePos = state.overlayPos = 0;
50
56
 
51
57
  if (state.overlayCur == null) return state.baseCur;
52
58
  if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
@@ -139,6 +139,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
139
139
  for (var i = 0, e = lines.length; i < e; ++i) {
140
140
  if (i) callback("\n");
141
141
  var stream = new CodeMirror.StringStream(lines[i]);
142
+ if (!stream.string && mode.blankLine) mode.blankLine();
142
143
  while (!stream.eol()) {
143
144
  var style = mode.token(stream, state);
144
145
  callback(stream.current(), style, i, stream.start, state);
@@ -57,6 +57,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
57
57
  for (var i = 0, e = lines.length; i < e; ++i) {
58
58
  if (i) callback("\n");
59
59
  var stream = new CodeMirror.StringStream(lines[i]);
60
+ if (!stream.string && mode.blankLine) mode.blankLine();
60
61
  while (!stream.eol()) {
61
62
  var style = mode.token(stream, state);
62
63
  callback(stream.current(), style, i, stream.start, state);
@@ -107,6 +107,7 @@ exports.runMode = function(string, modespec, callback, options) {
107
107
  for (var i = 0, e = lines.length; i < e; ++i) {
108
108
  if (i) callback("\n");
109
109
  var stream = new exports.StringStream(lines[i]);
110
+ if (!stream.string && mode.blankLine) mode.blankLine();
110
111
  while (!stream.eol()) {
111
112
  var style = mode.token(stream, state);
112
113
  callback(stream.current(), style, i, stream.start, state);
@@ -16,21 +16,21 @@
16
16
  })(function(CodeMirror) {
17
17
  "use strict";
18
18
  function searchOverlay(query, caseInsensitive) {
19
- var startChar;
20
- if (typeof query == "string") {
21
- startChar = query.charAt(0);
22
- query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
23
- caseInsensitive ? "i" : "");
24
- } else {
25
- query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
26
- }
19
+ if (typeof query == "string")
20
+ query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
21
+ else if (!query.global)
22
+ query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
23
+
27
24
  return {token: function(stream) {
28
- if (stream.match(query)) return "searching";
29
- while (!stream.eol()) {
30
- stream.next();
31
- if (startChar && !caseInsensitive)
32
- stream.skipTo(startChar) || stream.skipToEnd();
33
- if (stream.match(query, false)) break;
25
+ query.lastIndex = stream.pos;
26
+ var match = query.exec(stream.string);
27
+ if (match && match.index == stream.pos) {
28
+ stream.pos += match[0].length;
29
+ return "searching";
30
+ } else if (match) {
31
+ stream.pos = match.index;
32
+ } else {
33
+ stream.skipToEnd();
34
34
  }
35
35
  }};
36
36
  }