codemirror-rails 5.4 → 5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +88 -35
  4. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +10 -7
  5. data/vendor/assets/javascripts/codemirror/addons/search/search.js +52 -17
  6. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +1 -1
  7. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
  8. data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +4 -2
  9. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +1 -1
  10. data/vendor/assets/javascripts/codemirror/modes/brainfuck.js +85 -0
  11. data/vendor/assets/javascripts/codemirror/modes/clike.js +13 -0
  12. data/vendor/assets/javascripts/codemirror/modes/css.js +2 -0
  13. data/vendor/assets/javascripts/codemirror/modes/erlang.js +0 -4
  14. data/vendor/assets/javascripts/codemirror/modes/gfm.js +3 -2
  15. data/vendor/assets/javascripts/codemirror/modes/markdown.js +7 -7
  16. data/vendor/assets/javascripts/codemirror/modes/ruby.js +1 -1
  17. data/vendor/assets/javascripts/codemirror/modes/rust.js +1 -1
  18. data/vendor/assets/javascripts/codemirror/modes/vhdl.js +189 -0
  19. data/vendor/assets/javascripts/codemirror/modes/xml.js +1 -0
  20. data/vendor/assets/stylesheets/codemirror.css +19 -12
  21. data/vendor/assets/stylesheets/codemirror/addons/tern/tern.css +1 -0
  22. data/vendor/assets/stylesheets/codemirror/themes/3024-day.css +3 -2
  23. data/vendor/assets/stylesheets/codemirror/themes/3024-night.css +2 -2
  24. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +2 -2
  25. data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +2 -2
  26. data/vendor/assets/stylesheets/codemirror/themes/base16-light.css +2 -2
  27. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +2 -2
  28. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +2 -2
  29. data/vendor/assets/stylesheets/codemirror/themes/dracula.css +87 -0
  30. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +2 -2
  31. data/vendor/assets/stylesheets/codemirror/themes/icecoder.css +42 -0
  32. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +2 -2
  33. data/vendor/assets/stylesheets/codemirror/themes/material.css +105 -0
  34. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +2 -2
  35. data/vendor/assets/stylesheets/codemirror/themes/mdn-like.css +2 -2
  36. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +2 -2
  37. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +2 -2
  38. data/vendor/assets/stylesheets/codemirror/themes/night.css +2 -2
  39. data/vendor/assets/stylesheets/codemirror/themes/paraiso-dark.css +2 -2
  40. data/vendor/assets/stylesheets/codemirror/themes/paraiso-light.css +2 -2
  41. data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +2 -2
  42. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -2
  43. data/vendor/assets/stylesheets/codemirror/themes/seti.css +88 -0
  44. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +3 -3
  45. data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +2 -2
  46. data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-eighties.css +2 -2
  47. data/vendor/assets/stylesheets/codemirror/themes/twilight.css +2 -2
  48. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +2 -2
  49. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +2 -2
  50. data/vendor/assets/stylesheets/codemirror/themes/yeti.css +86 -0
  51. metadata +8 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10db6f811f18415146339d089880eed31b6fa1e2
4
- data.tar.gz: 2d6da2b335ed897e73bfd5b8b215cc3707103c90
3
+ metadata.gz: 9653550a47590b85abbf8924efa06589e5e525ec
4
+ data.tar.gz: 575475714f3369c55478f451f7af4d8cd06b87e3
5
5
  SHA512:
6
- metadata.gz: fa0289f78e21921fed008e0a050114cae82355ce4c4da0788256d488e491ef85f4f1ab617a8c0d19f725b493313b6b2164657cb15bdbc725ec2a6aa4f45e407e
7
- data.tar.gz: c7f55bed88131340665ae6b7685d454a57a6acc65ab8aecee48985d407fba3bdb104757bb8274091d10fa6c7072308936bcffc62e7af4fc0d75a938fe3e484a0
6
+ metadata.gz: fda74337e21a23dc3c55ff3ed93de8015234e7360b38b2c7b34136de561d6af0bb65c1c803bb0b4eab3f4ef50db6f1b144975bf31c0c8442125185f41789aea1
7
+ data.tar.gz: ba3c3869dcee61b638ba6a5dfe37a1c1b09f3574e7faeac1148eac39bf53c0f2284ead29b6baf2550e4b5841d314446c3f866d53b81e20cf32428fcc8ac5bc70
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '5.4'
4
- CODEMIRROR_VERSION = '5.4'
3
+ VERSION = '5.5'
4
+ CODEMIRROR_VERSION = '5.5'
5
5
  end
6
6
  end
@@ -65,7 +65,7 @@
65
65
  setGuttersForLineNumbers(options);
66
66
 
67
67
  var doc = options.value;
68
- if (typeof doc == "string") doc = new Doc(doc, options.mode);
68
+ if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
69
69
  this.doc = doc;
70
70
 
71
71
  var input = new CodeMirror.inputStyles[options.inputStyle](this);
@@ -714,7 +714,7 @@
714
714
  // width and height.
715
715
  removeChildren(display.cursorDiv);
716
716
  removeChildren(display.selectionDiv);
717
- display.gutters.style.height = 0;
717
+ display.gutters.style.height = display.sizer.style.minHeight = 0;
718
718
 
719
719
  if (different) {
720
720
  display.lastWrapHeight = update.wrapperHeight;
@@ -955,12 +955,22 @@
955
955
  lineView.node.removeChild(lineView.gutter);
956
956
  lineView.gutter = null;
957
957
  }
958
+ if (lineView.gutterBackground) {
959
+ lineView.node.removeChild(lineView.gutterBackground);
960
+ lineView.gutterBackground = null;
961
+ }
962
+ if (lineView.line.gutterClass) {
963
+ var wrap = ensureLineWrapped(lineView);
964
+ lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
965
+ "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
966
+ "px; width: " + dims.gutterTotalWidth + "px");
967
+ wrap.insertBefore(lineView.gutterBackground, lineView.text);
968
+ }
958
969
  var markers = lineView.line.gutterMarkers;
959
970
  if (cm.options.lineNumbers || markers) {
960
971
  var wrap = ensureLineWrapped(lineView);
961
972
  var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
962
- (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
963
- "px; width: " + dims.gutterTotalWidth + "px");
973
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
964
974
  cm.display.input.setUneditable(gutterWrap);
965
975
  wrap.insertBefore(gutterWrap, lineView.text);
966
976
  if (lineView.line.gutterClass)
@@ -1082,13 +1092,18 @@
1082
1092
  if (!sel) sel = doc.sel;
1083
1093
 
1084
1094
  var paste = cm.state.pasteIncoming || origin == "paste";
1085
- var textLines = splitLines(inserted), multiPaste = null;
1095
+ var textLines = doc.splitLines(inserted), multiPaste = null;
1086
1096
  // When pasing N lines into N selections, insert one line per selection
1087
1097
  if (paste && sel.ranges.length > 1) {
1088
- if (lastCopied && lastCopied.join("\n") == inserted)
1089
- multiPaste = sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
1090
- else if (textLines.length == sel.ranges.length)
1098
+ if (lastCopied && lastCopied.join("\n") == inserted) {
1099
+ if (sel.ranges.length % lastCopied.length == 0) {
1100
+ multiPaste = [];
1101
+ for (var i = 0; i < lastCopied.length; i++)
1102
+ multiPaste.push(doc.splitLines(lastCopied[i]));
1103
+ }
1104
+ } else if (textLines.length == sel.ranges.length) {
1091
1105
  multiPaste = map(textLines, function(l) { return [l]; });
1106
+ }
1092
1107
  }
1093
1108
 
1094
1109
  // Normal behavior is to insert the new text into every selection
@@ -1388,7 +1403,7 @@
1388
1403
  // will be the case when there is a lot of text in the textarea,
1389
1404
  // in which case reading its value would be expensive.
1390
1405
  if (this.contextMenuPending || !cm.state.focused ||
1391
- (hasSelection(input) && !prevInput) ||
1406
+ (hasSelection(input) && !prevInput && !this.composing) ||
1392
1407
  isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
1393
1408
  return false;
1394
1409
 
@@ -1756,7 +1771,7 @@
1756
1771
  var toNode = display.view[toIndex + 1].node.previousSibling;
1757
1772
  }
1758
1773
 
1759
- var newText = splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
1774
+ var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
1760
1775
  var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
1761
1776
  while (newText.length > 1 && oldText.length > 1) {
1762
1777
  if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
@@ -1912,7 +1927,7 @@
1912
1927
  }
1913
1928
 
1914
1929
  function domTextBetween(cm, from, to, fromLine, toLine) {
1915
- var text = "", closing = false;
1930
+ var text = "", closing = false, lineSep = cm.doc.lineSeparator();
1916
1931
  function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
1917
1932
  function walk(node) {
1918
1933
  if (node.nodeType == 1) {
@@ -1926,7 +1941,7 @@
1926
1941
  if (markerID) {
1927
1942
  var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
1928
1943
  if (found.length && (range = found[0].find()))
1929
- text += getBetween(cm.doc, range.from, range.to).join("\n");
1944
+ text += getBetween(cm.doc, range.from, range.to).join(lineSep);
1930
1945
  return;
1931
1946
  }
1932
1947
  if (node.getAttribute("contenteditable") == "false") return;
@@ -1938,7 +1953,7 @@
1938
1953
  var val = node.nodeValue;
1939
1954
  if (!val) return;
1940
1955
  if (closing) {
1941
- text += "\n";
1956
+ text += lineSep;
1942
1957
  closing = false;
1943
1958
  }
1944
1959
  text += val;
@@ -2545,10 +2560,12 @@
2545
2560
  function prepareMeasureForLine(cm, line) {
2546
2561
  var lineN = lineNo(line);
2547
2562
  var view = findViewForLine(cm, lineN);
2548
- if (view && !view.text)
2563
+ if (view && !view.text) {
2549
2564
  view = null;
2550
- else if (view && view.changes)
2565
+ } else if (view && view.changes) {
2551
2566
  updateLineForChanges(cm, view, lineN, getDimensions(cm));
2567
+ cm.curOp.forceUpdate = true;
2568
+ }
2552
2569
  if (!view)
2553
2570
  view = updateExternalMeasurement(cm, line);
2554
2571
 
@@ -3785,7 +3802,9 @@
3785
3802
  text[i] = reader.result;
3786
3803
  if (++read == n) {
3787
3804
  pos = clipPos(cm.doc, pos);
3788
- var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
3805
+ var change = {from: pos, to: pos,
3806
+ text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
3807
+ origin: "paste"};
3789
3808
  makeChange(cm.doc, change);
3790
3809
  setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
3791
3810
  }
@@ -4468,7 +4487,7 @@
4468
4487
  function replaceRange(doc, code, from, to, origin) {
4469
4488
  if (!to) to = from;
4470
4489
  if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
4471
- if (typeof code == "string") code = splitLines(code);
4490
+ if (typeof code == "string") code = doc.splitLines(code);
4472
4491
  makeChange(doc, {from: from, to: to, text: code, origin: origin});
4473
4492
  }
4474
4493
 
@@ -5263,6 +5282,22 @@
5263
5282
  clearCaches(cm);
5264
5283
  regChange(cm);
5265
5284
  }, true);
5285
+ option("lineSeparator", null, function(cm, val) {
5286
+ cm.doc.lineSep = val;
5287
+ if (!val) return;
5288
+ var newBreaks = [], lineNo = cm.doc.first;
5289
+ cm.doc.iter(function(line) {
5290
+ for (var pos = 0;;) {
5291
+ var found = line.text.indexOf(val, pos);
5292
+ if (found == -1) break;
5293
+ pos = found + val.length;
5294
+ newBreaks.push(Pos(lineNo, found));
5295
+ }
5296
+ lineNo++;
5297
+ });
5298
+ for (var i = newBreaks.length - 1; i >= 0; i--)
5299
+ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length))
5300
+ });
5266
5301
  option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
5267
5302
  cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
5268
5303
  if (old != CodeMirror.Init) cm.refresh();
@@ -5613,7 +5648,8 @@
5613
5648
  } else if (cur.line > cm.doc.first) {
5614
5649
  var prev = getLine(cm.doc, cur.line - 1).text;
5615
5650
  if (prev)
5616
- cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
5651
+ cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
5652
+ prev.charAt(prev.length - 1),
5617
5653
  Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
5618
5654
  }
5619
5655
  }
@@ -5627,7 +5663,7 @@
5627
5663
  var len = cm.listSelections().length;
5628
5664
  for (var i = 0; i < len; i++) {
5629
5665
  var range = cm.listSelections()[i];
5630
- cm.replaceRange("\n", range.anchor, range.head, "+input");
5666
+ cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input");
5631
5667
  cm.indentLine(range.from().line + 1, null, true);
5632
5668
  ensureCursorVisible(cm);
5633
5669
  }
@@ -6791,7 +6827,7 @@
6791
6827
  // is needed on Webkit to be able to get line-level bounding
6792
6828
  // rectangles for it (in measureChar).
6793
6829
  var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
6794
- var builder = {pre: elt("pre", [content]), content: content,
6830
+ var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
6795
6831
  col: 0, pos: 0, cm: cm,
6796
6832
  splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
6797
6833
  lineView.measure = {};
@@ -6881,6 +6917,10 @@
6881
6917
  txt.setAttribute("role", "presentation");
6882
6918
  txt.setAttribute("cm-text", "\t");
6883
6919
  builder.col += tabWidth;
6920
+ } else if (m[0] == "\r" || m[0] == "\n") {
6921
+ var txt = content.appendChild(elt("span", m[0] == "\r" ? "␍" : "␤", "cm-invalidchar"));
6922
+ txt.setAttribute("cm-text", m[0]);
6923
+ builder.col += 1;
6884
6924
  } else {
6885
6925
  var txt = builder.cm.options.specialCharPlaceholder(m[0]);
6886
6926
  txt.setAttribute("cm-text", m[0]);
@@ -7226,8 +7266,8 @@
7226
7266
  };
7227
7267
 
7228
7268
  var nextDocId = 0;
7229
- var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
7230
- if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
7269
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) {
7270
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep);
7231
7271
  if (firstLine == null) firstLine = 0;
7232
7272
 
7233
7273
  BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
@@ -7241,8 +7281,9 @@
7241
7281
  this.history = new History(null);
7242
7282
  this.id = ++nextDocId;
7243
7283
  this.modeOption = mode;
7284
+ this.lineSep = lineSep;
7244
7285
 
7245
- if (typeof text == "string") text = splitLines(text);
7286
+ if (typeof text == "string") text = this.splitLines(text);
7246
7287
  updateDoc(this, {from: start, to: start, text: text});
7247
7288
  setSelection(this, simpleSelection(start), sel_dontScroll);
7248
7289
  };
@@ -7272,12 +7313,12 @@
7272
7313
  getValue: function(lineSep) {
7273
7314
  var lines = getLines(this, this.first, this.first + this.size);
7274
7315
  if (lineSep === false) return lines;
7275
- return lines.join(lineSep || "\n");
7316
+ return lines.join(lineSep || this.lineSeparator());
7276
7317
  },
7277
7318
  setValue: docMethodOp(function(code) {
7278
7319
  var top = Pos(this.first, 0), last = this.first + this.size - 1;
7279
7320
  makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
7280
- text: splitLines(code), origin: "setValue", full: true}, true);
7321
+ text: this.splitLines(code), origin: "setValue", full: true}, true);
7281
7322
  setSelection(this, simpleSelection(top));
7282
7323
  }),
7283
7324
  replaceRange: function(code, from, to, origin) {
@@ -7288,7 +7329,7 @@
7288
7329
  getRange: function(from, to, lineSep) {
7289
7330
  var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
7290
7331
  if (lineSep === false) return lines;
7291
- return lines.join(lineSep || "\n");
7332
+ return lines.join(lineSep || this.lineSeparator());
7292
7333
  },
7293
7334
 
7294
7335
  getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
@@ -7354,13 +7395,13 @@
7354
7395
  lines = lines ? lines.concat(sel) : sel;
7355
7396
  }
7356
7397
  if (lineSep === false) return lines;
7357
- else return lines.join(lineSep || "\n");
7398
+ else return lines.join(lineSep || this.lineSeparator());
7358
7399
  },
7359
7400
  getSelections: function(lineSep) {
7360
7401
  var parts = [], ranges = this.sel.ranges;
7361
7402
  for (var i = 0; i < ranges.length; i++) {
7362
7403
  var sel = getBetween(this, ranges[i].from(), ranges[i].to());
7363
- if (lineSep !== false) sel = sel.join(lineSep || "\n");
7404
+ if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator());
7364
7405
  parts[i] = sel;
7365
7406
  }
7366
7407
  return parts;
@@ -7375,7 +7416,7 @@
7375
7416
  var changes = [], sel = this.sel;
7376
7417
  for (var i = 0; i < sel.ranges.length; i++) {
7377
7418
  var range = sel.ranges[i];
7378
- changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
7419
+ changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
7379
7420
  }
7380
7421
  var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
7381
7422
  for (var i = changes.length - 1; i >= 0; i--)
@@ -7525,7 +7566,8 @@
7525
7566
  },
7526
7567
 
7527
7568
  copy: function(copyHistory) {
7528
- var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
7569
+ var doc = new Doc(getLines(this, this.first, this.first + this.size),
7570
+ this.modeOption, this.first, this.lineSep);
7529
7571
  doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
7530
7572
  doc.sel = this.sel;
7531
7573
  doc.extend = false;
@@ -7541,7 +7583,7 @@
7541
7583
  var from = this.first, to = this.first + this.size;
7542
7584
  if (options.from != null && options.from > from) from = options.from;
7543
7585
  if (options.to != null && options.to < to) to = options.to;
7544
- var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
7586
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep);
7545
7587
  if (options.sharedHist) copy.history = this.history;
7546
7588
  (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
7547
7589
  copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
@@ -7570,7 +7612,13 @@
7570
7612
  iterLinkedDocs: function(f) {linkedDocs(this, f);},
7571
7613
 
7572
7614
  getMode: function() {return this.mode;},
7573
- getEditor: function() {return this.cm;}
7615
+ getEditor: function() {return this.cm;},
7616
+
7617
+ splitLines: function(str) {
7618
+ if (this.lineSep) return str.split(this.lineSep);
7619
+ return splitLinesAuto(str);
7620
+ },
7621
+ lineSeparator: function() { return this.lineSep || "\n"; }
7574
7622
  });
7575
7623
 
7576
7624
  // Public alias.
@@ -8269,7 +8317,12 @@
8269
8317
  } while (child = child.parentNode);
8270
8318
  };
8271
8319
 
8272
- function activeElt() { return document.activeElement; }
8320
+ function activeElt() {
8321
+ var activeElement = document.activeElement;
8322
+ while (activeElement && activeElement.root && activeElement.root.activeElement)
8323
+ activeElement = activeElement.root.activeElement;
8324
+ return activeElement;
8325
+ }
8273
8326
  // Older versions of IE throws unspecified error when touching
8274
8327
  // document.activeElement in some cases (during loading, in iframe)
8275
8328
  if (ie && ie_version < 11) activeElt = function() {
@@ -8371,7 +8424,7 @@
8371
8424
 
8372
8425
  // See if "".split is the broken IE version, if so, provide an
8373
8426
  // alternative way to split lines.
8374
- var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
8427
+ var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
8375
8428
  var pos = 0, result = [], l = string.length;
8376
8429
  while (pos <= l) {
8377
8430
  var nl = string.indexOf("\n", pos);
@@ -8729,7 +8782,7 @@
8729
8782
 
8730
8783
  // THE END
8731
8784
 
8732
- CodeMirror.version = "5.4.0";
8785
+ CodeMirror.version = "5.5.0";
8733
8786
 
8734
8787
  return CodeMirror;
8735
8788
  });
@@ -99,7 +99,6 @@
99
99
 
100
100
  update: function(first) {
101
101
  if (this.tick == null) return;
102
- if (this.data) CodeMirror.signal(this.data, "update");
103
102
  if (!this.options.hint.async) {
104
103
  this.finishUpdate(this.options.hint(this.cm, this.options), first);
105
104
  } else {
@@ -111,6 +110,8 @@
111
110
  },
112
111
 
113
112
  finishUpdate: function(data, first) {
113
+ if (this.data) CodeMirror.signal(this.data, "update");
114
+ if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
114
115
  this.data = data;
115
116
 
116
117
  var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
@@ -351,18 +352,20 @@
351
352
 
352
353
  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
353
354
  var cur = cm.getCursor(), token = cm.getTokenAt(cur);
355
+ var to = CodeMirror.Pos(cur.line, token.end);
356
+ if (token.string && /\w/.test(token.string[token.string.length - 1])) {
357
+ var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
358
+ } else {
359
+ var term = "", from = to;
360
+ }
354
361
  var found = [];
355
362
  for (var i = 0; i < options.words.length; i++) {
356
363
  var word = options.words[i];
357
- if (word.slice(0, token.string.length) == token.string)
364
+ if (word.slice(0, term.length) == term)
358
365
  found.push(word);
359
366
  }
360
367
 
361
- if (found.length) return {
362
- list: found,
363
- from: CodeMirror.Pos(cur.line, token.start),
364
- to: CodeMirror.Pos(cur.line, token.end)
365
- };
368
+ if (found.length) return {list: found, from: from, to: to};
366
369
  });
367
370
 
368
371
  CodeMirror.commands.autocomplete = CodeMirror.showHint;
@@ -18,6 +18,7 @@
18
18
  mod(CodeMirror);
19
19
  })(function(CodeMirror) {
20
20
  "use strict";
21
+
21
22
  function searchOverlay(query, caseInsensitive) {
22
23
  if (typeof query == "string")
23
24
  query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
@@ -42,24 +43,39 @@
42
43
  this.posFrom = this.posTo = this.lastQuery = this.query = null;
43
44
  this.overlay = null;
44
45
  }
46
+
45
47
  function getSearchState(cm) {
46
48
  return cm.state.search || (cm.state.search = new SearchState());
47
49
  }
50
+
48
51
  function queryCaseInsensitive(query) {
49
52
  return typeof query == "string" && query == query.toLowerCase();
50
53
  }
54
+
51
55
  function getSearchCursor(cm, query, pos) {
52
56
  // Heuristic: if the query string is all lowercase, do a case insensitive search.
53
57
  return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
54
58
  }
59
+
60
+ function persistentDialog(cm, text, deflt, f) {
61
+ cm.openDialog(text, f, {
62
+ value: deflt,
63
+ selectValueOnOpen: true,
64
+ closeOnEnter: false,
65
+ onClose: function() { clearSearch(cm); }
66
+ });
67
+ }
68
+
55
69
  function dialog(cm, text, shortText, deflt, f) {
56
70
  if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
57
71
  else f(prompt(shortText, deflt));
58
72
  }
73
+
59
74
  function confirmDialog(cm, text, shortText, fs) {
60
75
  if (cm.openConfirm) cm.openConfirm(text, fs);
61
76
  else if (confirm(shortText)) fs[0]();
62
77
  }
78
+
63
79
  function parseQuery(query) {
64
80
  var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
65
81
  if (isRE) {
@@ -70,28 +86,44 @@
70
86
  query = /x^/;
71
87
  return query;
72
88
  }
89
+
73
90
  var queryDialog =
74
91
  'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
75
- function doSearch(cm, rev) {
92
+
93
+ function startSearch(cm, state, query) {
94
+ state.queryText = query;
95
+ state.query = parseQuery(query);
96
+ cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
97
+ state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
98
+ cm.addOverlay(state.overlay);
99
+ if (cm.showMatchesOnScrollbar) {
100
+ if (state.annotate) { state.annotate.clear(); state.annotate = null; }
101
+ state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
102
+ }
103
+ }
104
+
105
+ function doSearch(cm, rev, persistent) {
76
106
  var state = getSearchState(cm);
77
107
  if (state.query) return findNext(cm, rev);
78
108
  var q = cm.getSelection() || state.lastQuery;
79
- dialog(cm, queryDialog, "Search for:", q, function(query) {
80
- cm.operation(function() {
81
- if (!query || state.query) return;
82
- state.query = parseQuery(query);
83
- cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
84
- state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
85
- cm.addOverlay(state.overlay);
86
- if (cm.showMatchesOnScrollbar) {
87
- if (state.annotate) { state.annotate.clear(); state.annotate = null; }
88
- state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
89
- }
90
- state.posFrom = state.posTo = cm.getCursor();
91
- findNext(cm, rev);
109
+ if (persistent && cm.openDialog) {
110
+ persistentDialog(cm, queryDialog, q, function(query, event) {
111
+ CodeMirror.e_stop(event);
112
+ if (!query) return;
113
+ if (query != state.queryText) startSearch(cm, state, query);
114
+ findNext(cm, event.shiftKey);
92
115
  });
93
- });
116
+ } else {
117
+ dialog(cm, queryDialog, "Search for:", q, function(query) {
118
+ if (query && !state.query) cm.operation(function() {
119
+ startSearch(cm, state, query);
120
+ state.posFrom = state.posTo = cm.getCursor();
121
+ findNext(cm, rev);
122
+ });
123
+ });
124
+ }
94
125
  }
126
+
95
127
  function findNext(cm, rev) {cm.operation(function() {
96
128
  var state = getSearchState(cm);
97
129
  var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
@@ -100,14 +132,15 @@
100
132
  if (!cursor.find(rev)) return;
101
133
  }
102
134
  cm.setSelection(cursor.from(), cursor.to());
103
- cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
135
+ cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
104
136
  state.posFrom = cursor.from(); state.posTo = cursor.to();
105
137
  });}
138
+
106
139
  function clearSearch(cm) {cm.operation(function() {
107
140
  var state = getSearchState(cm);
108
141
  state.lastQuery = state.query;
109
142
  if (!state.query) return;
110
- state.query = null;
143
+ state.query = state.queryText = null;
111
144
  cm.removeOverlay(state.overlay);
112
145
  if (state.annotate) { state.annotate.clear(); state.annotate = null; }
113
146
  });}
@@ -116,6 +149,7 @@
116
149
  'Replace: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
117
150
  var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
118
151
  var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
152
+
119
153
  function replace(cm, all) {
120
154
  if (cm.getOption("readOnly")) return;
121
155
  var query = cm.getSelection() || getSearchState(cm).lastQuery;
@@ -159,6 +193,7 @@
159
193
  }
160
194
 
161
195
  CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
196
+ CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
162
197
  CodeMirror.commands.findNext = doSearch;
163
198
  CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
164
199
  CodeMirror.commands.clearSearch = clearSearch;