codemirror-rails 4.4 → 4.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8f231dd42a91b4d2a0ecc9440cad8f8e505f239d
4
- data.tar.gz: 3482d82a48c052c4472c55a0db8a648fb87e0b87
3
+ metadata.gz: 3e059cb95f28ccd6359e88ac0b4ff11c1051ac03
4
+ data.tar.gz: d8ee9576a123228b1ca810588700a3af42dbfbc0
5
5
  SHA512:
6
- metadata.gz: 0989abb66c57e0f95cb9f20646f797c6eb296da0d1a87845379ea52db4488e24458bd40e61176d0125433abb0b7c6fc4dca586a0b4dcfe66273742ccb0a7973b
7
- data.tar.gz: 74161b00c7c25f04c3468e58e304f989691cc6cc5c51c3017c7471f9f2112dc5a39a31779d960b9be3813ca28774b30a1ed9ca201e381f546c66bc2a1b571138
6
+ metadata.gz: 429201482a115f18936a9e2950a9ee0e4b26e3c851e31fe124d5fc1949247b7b90b50ba98626a5e223c5479c8e49ebc1b6a6d555b95f566211b776d9a36987d6
7
+ data.tar.gz: 861ebb1342b708ee8c82d675f82da91f14f63a54d484e94ad07c2ea2d044da39a9f17591036677924f7c7fba6223674570cec78284b38c9009f35a29b7bc7008
@@ -1,6 +1,6 @@
1
1
  module Codemirror
2
2
  module Rails
3
- VERSION = '4.4'
4
- CODEMIRROR_VERSION = '4.4'
3
+ VERSION = '4.5'
4
+ CODEMIRROR_VERSION = '4.5'
5
5
  end
6
6
  end
@@ -662,6 +662,7 @@
662
662
  function updateDisplaySimple(cm, viewport) {
663
663
  var update = new DisplayUpdate(cm, viewport);
664
664
  if (updateDisplayIfNeeded(cm, update)) {
665
+ updateHeightsInViewport(cm);
665
666
  postUpdateDisplay(cm, update);
666
667
  var barMeasure = measureForScrollbars(cm);
667
668
  updateSelection(cm);
@@ -1280,8 +1281,7 @@
1280
1281
  return result;
1281
1282
  }
1282
1283
 
1283
- function updateSelection(cm, drawn) {
1284
- if (!drawn) drawn = drawSelection(cm);
1284
+ function showSelection(cm, drawn) {
1285
1285
  removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
1286
1286
  removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
1287
1287
  if (drawn.teTop != null) {
@@ -1290,6 +1290,10 @@
1290
1290
  }
1291
1291
  }
1292
1292
 
1293
+ function updateSelection(cm) {
1294
+ showSelection(cm, drawSelection(cm));
1295
+ }
1296
+
1293
1297
  // Draws a cursor for the given range
1294
1298
  function drawSelectionCursor(cm, range, output) {
1295
1299
  var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
@@ -1642,18 +1646,24 @@
1642
1646
 
1643
1647
  var rect;
1644
1648
  if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
1645
- while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
1646
- while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
1647
- if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
1648
- rect = node.parentNode.getBoundingClientRect();
1649
- } else if (ie && cm.options.lineWrapping) {
1650
- var rects = range(node, start, end).getClientRects();
1651
- if (rects.length)
1652
- rect = rects[bias == "right" ? rects.length - 1 : 0];
1653
- else
1654
- rect = nullRect;
1655
- } else {
1656
- rect = range(node, start, end).getBoundingClientRect() || nullRect;
1649
+ for (;;) {
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";
1657
1667
  }
1658
1668
  } else { // If it is a widget, simply get the box for the whole widget.
1659
1669
  if (start > 0) collapse = bias = "right";
@@ -2029,16 +2039,17 @@
2029
2039
  var cm = op.cm, display = cm.display;
2030
2040
  if (op.updatedDisplay) updateHeightsInViewport(cm);
2031
2041
 
2042
+ op.barMeasure = measureForScrollbars(cm);
2043
+
2032
2044
  // If the max line changed since it was last measured, measure it,
2033
2045
  // and ensure the document's width matches it.
2034
- // updateDisplayIfNeeded will use these properties to do the actual resizing
2046
+ // updateDisplay_W2 will use these properties to do the actual resizing
2035
2047
  if (display.maxLineChanged && !cm.options.lineWrapping) {
2036
- op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left;
2048
+ op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
2037
2049
  op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo +
2038
2050
  scrollerCutOff - display.scroller.clientWidth);
2039
2051
  }
2040
2052
 
2041
- op.barMeasure = measureForScrollbars(cm);
2042
2053
  if (op.updatedDisplay || op.selectionChanged)
2043
2054
  op.newSelectionNodes = drawSelection(cm);
2044
2055
  }
@@ -2050,10 +2061,11 @@
2050
2061
  cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
2051
2062
  if (op.maxScrollLeft < cm.doc.scrollLeft)
2052
2063
  setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
2064
+ cm.display.maxLineChanged = false;
2053
2065
  }
2054
2066
 
2055
2067
  if (op.newSelectionNodes)
2056
- updateSelection(cm, op.newSelectionNodes);
2068
+ showSelection(cm, op.newSelectionNodes);
2057
2069
  if (op.updatedDisplay)
2058
2070
  setDocumentHeight(cm, op.barMeasure);
2059
2071
  if (op.updatedDisplay || op.startHeight != cm.doc.height)
@@ -2068,6 +2080,9 @@
2068
2080
  function endOperation_finish(op) {
2069
2081
  var cm = op.cm, display = cm.display, doc = cm.doc;
2070
2082
 
2083
+ if (op.adjustWidthTo != null && Math.abs(op.barMeasure.scrollWidth - cm.display.scroller.scrollWidth) > 1)
2084
+ updateScrollbars(cm);
2085
+
2071
2086
  if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
2072
2087
 
2073
2088
  // Abort mouse wheel delta measurement, when scrolling explicitly
@@ -3553,7 +3568,7 @@
3553
3568
 
3554
3569
  var after = i ? computeSelAfterChange(doc, change) : lst(source);
3555
3570
  makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
3556
- if (!i && doc.cm) doc.cm.scrollIntoView(change);
3571
+ if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
3557
3572
  var rebased = [];
3558
3573
 
3559
3574
  // Propagate to the linked documents
@@ -3742,6 +3757,7 @@
3742
3757
  if (y1 < 0) y1 = 0;
3743
3758
  var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
3744
3759
  var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
3760
+ if (y2 - y1 > screen) y2 = y1 + screen;
3745
3761
  var docBottom = cm.doc.height + paddingVert(display);
3746
3762
  var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
3747
3763
  if (y1 < screentop) {
@@ -3752,16 +3768,16 @@
3752
3768
  }
3753
3769
 
3754
3770
  var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
3755
- var screenw = display.scroller.clientWidth - scrollerCutOff;
3756
- x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
3757
- var gutterw = display.gutters.offsetWidth;
3758
- var atLeft = x1 < gutterw + 10;
3759
- if (x1 < screenleft + gutterw || atLeft) {
3760
- if (atLeft) x1 = 0;
3761
- result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
3762
- } else if (x2 > screenw + screenleft - 3) {
3763
- result.scrollLeft = x2 + 10 - screenw;
3764
- }
3771
+ var screenw = display.scroller.clientWidth - scrollerCutOff - display.gutters.offsetWidth;
3772
+ var tooWide = x2 - x1 > screenw;
3773
+ if (tooWide) x2 = y1 + screen;
3774
+ if (x1 < 10)
3775
+ result.scrollLeft = 0;
3776
+ else if (x1 < screenleft)
3777
+ result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
3778
+ else if (x2 > screenw + screenleft - 3)
3779
+ result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
3780
+
3765
3781
  return result;
3766
3782
  }
3767
3783
 
@@ -4070,11 +4086,14 @@
4070
4086
  for (var i = 0; i < ranges.length; i++) {
4071
4087
  var range = ranges[i];
4072
4088
  if (!range.empty()) {
4073
- var start = Math.max(end, range.from().line);
4074
- var to = range.to();
4089
+ var from = range.from(), to = range.to();
4090
+ var start = Math.max(end, from.line);
4075
4091
  end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
4076
4092
  for (var j = start; j < end; ++j)
4077
4093
  indentLine(this, j, how);
4094
+ var newRanges = this.doc.sel.ranges;
4095
+ if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
4096
+ replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
4078
4097
  } else if (range.head.line > end) {
4079
4098
  indentLine(this, range.head.line, how, true);
4080
4099
  end = range.head.line;
@@ -4470,7 +4489,7 @@
4470
4489
  clearCaches(cm);
4471
4490
  regChange(cm);
4472
4491
  }, true);
4473
- option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
4492
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val) {
4474
4493
  cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
4475
4494
  cm.refresh();
4476
4495
  }, true);
@@ -4731,15 +4750,7 @@
4731
4750
  },
4732
4751
  goLineStartSmart: function(cm) {
4733
4752
  cm.extendSelectionsBy(function(range) {
4734
- var start = lineStart(cm, range.head.line);
4735
- var line = cm.getLineHandle(start.line);
4736
- var order = getOrder(line);
4737
- if (!order || order[0].level == 0) {
4738
- var firstNonWS = Math.max(0, line.text.search(/\S/));
4739
- var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch;
4740
- return Pos(start.line, inWS ? 0 : firstNonWS);
4741
- }
4742
- return start;
4753
+ return lineStartSmart(cm, range.head);
4743
4754
  }, {origin: "+move", bias: 1});
4744
4755
  },
4745
4756
  goLineEnd: function(cm) {
@@ -4758,6 +4769,14 @@
4758
4769
  return cm.coordsChar({left: 0, top: top}, "div");
4759
4770
  }, sel_move);
4760
4771
  },
4772
+ goLineLeftSmart: function(cm) {
4773
+ cm.extendSelectionsBy(function(range) {
4774
+ var top = cm.charCoords(range.head, "div").top + 5;
4775
+ var pos = cm.coordsChar({left: 0, top: top}, "div");
4776
+ if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
4777
+ return pos;
4778
+ }, sel_move);
4779
+ },
4761
4780
  goLineUp: function(cm) {cm.moveV(-1, "line");},
4762
4781
  goLineDown: function(cm) {cm.moveV(1, "line");},
4763
4782
  goPageUp: function(cm) {cm.moveV(-1, "page");},
@@ -6495,7 +6514,7 @@
6495
6514
  },
6496
6515
  changeGeneration: function(forceSplit) {
6497
6516
  if (forceSplit)
6498
- this.history.lastOp = this.history.lastOrigin = null;
6517
+ this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
6499
6518
  return this.history.generation;
6500
6519
  },
6501
6520
  isClean: function (gen) {
@@ -6812,7 +6831,7 @@
6812
6831
  // Used to track when changes can be merged into a single undo
6813
6832
  // event
6814
6833
  this.lastModTime = this.lastSelTime = 0;
6815
- this.lastOp = null;
6834
+ this.lastOp = this.lastSelOp = null;
6816
6835
  this.lastOrigin = this.lastSelOrigin = null;
6817
6836
  // Used by the isClean() method
6818
6837
  this.generation = this.maxGeneration = startGen || 1;
@@ -6890,7 +6909,7 @@
6890
6909
  hist.done.push(selAfter);
6891
6910
  hist.generation = ++hist.maxGeneration;
6892
6911
  hist.lastModTime = hist.lastSelTime = time;
6893
- hist.lastOp = opId;
6912
+ hist.lastOp = hist.lastSelOp = opId;
6894
6913
  hist.lastOrigin = hist.lastSelOrigin = change.origin;
6895
6914
 
6896
6915
  if (!last) signal(doc, "historyAdded");
@@ -6916,7 +6935,7 @@
6916
6935
  // the current, or the origins don't allow matching. Origins
6917
6936
  // starting with * are always merged, those starting with + are
6918
6937
  // merged when similar and close together in time.
6919
- if (opId == hist.lastOp ||
6938
+ if (opId == hist.lastSelOp ||
6920
6939
  (origin && hist.lastSelOrigin == origin &&
6921
6940
  (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
6922
6941
  selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
@@ -6926,7 +6945,7 @@
6926
6945
 
6927
6946
  hist.lastSelTime = +new Date;
6928
6947
  hist.lastSelOrigin = origin;
6929
- hist.lastOp = opId;
6948
+ hist.lastSelOp = opId;
6930
6949
  if (options && options.clearRedo !== false)
6931
6950
  clearSelectionEvents(hist.undone);
6932
6951
  }
@@ -7556,6 +7575,17 @@
7556
7575
  var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
7557
7576
  return Pos(lineN == null ? lineNo(line) : lineN, ch);
7558
7577
  }
7578
+ function lineStartSmart(cm, pos) {
7579
+ var start = lineStart(cm, pos.line);
7580
+ var line = getLine(cm.doc, start.line);
7581
+ var order = getOrder(line);
7582
+ if (!order || order[0].level == 0) {
7583
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
7584
+ var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
7585
+ return Pos(start.line, inWS ? 0 : firstNonWS);
7586
+ }
7587
+ return start;
7588
+ }
7559
7589
 
7560
7590
  function compareBidiLevel(order, a, b) {
7561
7591
  var linedir = order[0].level;
@@ -7795,7 +7825,7 @@
7795
7825
 
7796
7826
  // THE END
7797
7827
 
7798
- CodeMirror.version = "4.4.0";
7828
+ CodeMirror.version = "4.5.0";
7799
7829
 
7800
7830
  return CodeMirror;
7801
7831
  });
@@ -157,12 +157,12 @@
157
157
  // Positions of the last startString before the start of the selection, and the first endString after it.
158
158
  var lastStart = startLine.lastIndexOf(startString, from.ch);
159
159
  var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
160
- if (lastStart != -1 && firstEnd != -1) return false;
160
+ if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
161
161
  // Positions of the first endString after the end of the selection, and the last startString before it.
162
162
  firstEnd = endLine.indexOf(endString, to.ch);
163
163
  var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
164
164
  lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
165
- if (firstEnd != -1 && lastStart != -1) return false;
165
+ if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
166
166
 
167
167
  self.operation(function() {
168
168
  self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
@@ -15,11 +15,11 @@
15
15
  var wrap = cm.getWrapperElement();
16
16
  var dialog;
17
17
  dialog = wrap.appendChild(document.createElement("div"));
18
- if (bottom) {
18
+ if (bottom)
19
19
  dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
20
- } else {
20
+ else
21
21
  dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
22
- }
22
+
23
23
  if (typeof template == "string") {
24
24
  dialog.innerHTML = template;
25
25
  } else { // Assuming it's a detached DOM element.
@@ -35,8 +35,11 @@
35
35
  }
36
36
 
37
37
  CodeMirror.defineExtension("openDialog", function(template, callback, options) {
38
+ if (!options) options = {};
39
+
38
40
  closeNotification(this, null);
39
- var dialog = dialogDiv(this, template, options && options.bottom);
41
+
42
+ var dialog = dialogDiv(this, template, options.bottom);
40
43
  var closed = false, me = this;
41
44
  function close(newVal) {
42
45
  if (typeof newVal == 'string') {
@@ -45,34 +48,43 @@
45
48
  if (closed) return;
46
49
  closed = true;
47
50
  dialog.parentNode.removeChild(dialog);
51
+ me.focus();
52
+
53
+ if (options.onClose) options.onClose(dialog);
48
54
  }
49
55
  }
56
+
50
57
  var inp = dialog.getElementsByTagName("input")[0], button;
51
58
  if (inp) {
52
- if (options && options.value) inp.value = options.value;
59
+ if (options.value) inp.value = options.value;
60
+
61
+ if (options.onInput)
62
+ CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
63
+ if (options.onKeyUp)
64
+ CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
65
+
53
66
  CodeMirror.on(inp, "keydown", function(e) {
54
67
  if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
55
- if (e.keyCode == 13 || e.keyCode == 27) {
68
+ if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
56
69
  inp.blur();
57
70
  CodeMirror.e_stop(e);
58
71
  close();
59
- me.focus();
60
- if (e.keyCode == 13) callback(inp.value);
61
72
  }
73
+ if (e.keyCode == 13) callback(inp.value);
62
74
  });
63
- if (options && options.onKeyUp) {
64
- CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
65
- }
66
- if (options && options.value) inp.value = options.value;
75
+
76
+ if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
77
+
67
78
  inp.focus();
68
- CodeMirror.on(inp, "blur", close);
69
79
  } else if (button = dialog.getElementsByTagName("button")[0]) {
70
80
  CodeMirror.on(button, "click", function() {
71
81
  close();
72
82
  me.focus();
73
83
  });
84
+
85
+ if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
86
+
74
87
  button.focus();
75
- CodeMirror.on(button, "blur", close);
76
88
  }
77
89
  return close;
78
90
  });
@@ -109,6 +109,10 @@
109
109
  replacements[i] = "/" + state.context.tagName + ">";
110
110
  }
111
111
  cm.replaceSelections(replacements);
112
+ ranges = cm.listSelections();
113
+ for (var i = 0; i < ranges.length; i++)
114
+ if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
115
+ cm.indentLine(ranges[i].head.line);
112
116
  }
113
117
 
114
118
  function indexOf(collection, elt) {
@@ -151,8 +151,9 @@
151
151
  if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
152
152
  var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
153
153
  var start = end && toTagStart(iter);
154
- if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
154
+ if (!end || !start || cmp(iter, pos) > 0) return;
155
155
  var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
156
+ if (end == "selfClose") return {open: here, close: null, at: "open"};
156
157
 
157
158
  if (start[1]) { // closing tag
158
159
  return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
@@ -21,7 +21,7 @@
21
21
 
22
22
  function getKeywords(editor) {
23
23
  var mode = editor.doc.modeOption;
24
- if(mode === "sql") mode = "text/x-sql";
24
+ if (mode === "sql") mode = "text/x-sql";
25
25
  return CodeMirror.resolveMode(mode).keywords;
26
26
  }
27
27
 
@@ -32,12 +32,12 @@
32
32
  }
33
33
 
34
34
  function addMatches(result, search, wordlist, formatter) {
35
- for(var word in wordlist) {
36
- if(!wordlist.hasOwnProperty(word)) continue;
37
- if(Array.isArray(wordlist)) {
35
+ for (var word in wordlist) {
36
+ if (!wordlist.hasOwnProperty(word)) continue;
37
+ if (Array.isArray(wordlist)) {
38
38
  word = wordlist[word];
39
39
  }
40
- if(match(search, word)) {
40
+ if (match(search, word)) {
41
41
  result.push(formatter(word));
42
42
  }
43
43
  }
@@ -49,33 +49,30 @@
49
49
  var string = token.string.substr(1);
50
50
  var prevCur = Pos(cur.line, token.start);
51
51
  var table = editor.getTokenAt(prevCur).string;
52
- if( !tables.hasOwnProperty( table ) ){
52
+ if (!tables.hasOwnProperty(table))
53
53
  table = findTableByAlias(table, editor);
54
- }
55
54
  var columns = tables[table];
56
- if(!columns) {
57
- return;
58
- }
59
- addMatches(result, string, columns,
60
- function(w) {return "." + w;});
55
+ if (!columns) return;
56
+
57
+ addMatches(result, string, columns, function(w) {return "." + w;});
61
58
  }
62
59
 
63
60
  function eachWord(lineText, f) {
64
- if( !lineText ){return;}
61
+ if (!lineText) return;
65
62
  var excepted = /[,;]/g;
66
- var words = lineText.split( " " );
67
- for( var i = 0; i < words.length; i++ ){
68
- f( words[i]?words[i].replace( excepted, '' ) : '' );
63
+ var words = lineText.split(" ");
64
+ for (var i = 0; i < words.length; i++) {
65
+ f(words[i]?words[i].replace(excepted, '') : '');
69
66
  }
70
67
  }
71
68
 
72
- function convertCurToNumber( cur ){
69
+ function convertCurToNumber(cur) {
73
70
  // max characters of a line is 999,999.
74
- return cur.line + cur.ch / Math.pow( 10, 6 );
71
+ return cur.line + cur.ch / Math.pow(10, 6);
75
72
  }
76
73
 
77
- function convertNumberToCur( num ){
78
- return Pos(Math.floor( num ), +num.toString().split( '.' ).pop());
74
+ function convertNumberToCur(num) {
75
+ return Pos(Math.floor(num), +num.toString().split('.').pop());
79
76
  }
80
77
 
81
78
  function findTableByAlias(alias, editor) {
@@ -86,26 +83,26 @@
86
83
  var table = "";
87
84
  var separator = [];
88
85
  var validRange = {
89
- start: Pos( 0, 0 ),
90
- end: Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).length )
86
+ start: Pos(0, 0),
87
+ end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
91
88
  };
92
89
 
93
90
  //add separator
94
- var indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV );
95
- while( indexOfSeparator != -1 ){
96
- separator.push( doc.posFromIndex(indexOfSeparator));
97
- indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV, indexOfSeparator+1);
91
+ var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
92
+ while(indexOfSeparator != -1) {
93
+ separator.push(doc.posFromIndex(indexOfSeparator));
94
+ indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
98
95
  }
99
- separator.unshift( Pos( 0, 0 ) );
100
- separator.push( Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).text.length ) );
96
+ separator.unshift(Pos(0, 0));
97
+ separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
101
98
 
102
- //find valieRange
99
+ //find valid range
103
100
  var prevItem = 0;
104
- var current = convertCurToNumber( editor.getCursor() );
105
- for( var i=0; i< separator.length; i++){
106
- var _v = convertCurToNumber( separator[i] );
107
- if( current > prevItem && current <= _v ){
108
- validRange = { start: convertNumberToCur( prevItem ), end: convertNumberToCur( _v ) };
101
+ var current = convertCurToNumber(editor.getCursor());
102
+ for (var i=0; i< separator.length; i++) {
103
+ var _v = convertCurToNumber(separator[i]);
104
+ if (current > prevItem && current <= _v) {
105
+ validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) };
109
106
  break;
110
107
  }
111
108
  prevItem = _v;
@@ -113,52 +110,51 @@
113
110
 
114
111
  var query = doc.getRange(validRange.start, validRange.end, false);
115
112
 
116
- for(var i=0; i < query.length; i++){
113
+ for (var i = 0; i < query.length; i++) {
117
114
  var lineText = query[i];
118
- eachWord( lineText, function( word ){
115
+ eachWord(lineText, function(word) {
119
116
  var wordUpperCase = word.toUpperCase();
120
- if( wordUpperCase === aliasUpperCase && tables.hasOwnProperty( previousWord ) ){
117
+ if (wordUpperCase === aliasUpperCase && tables.hasOwnProperty(previousWord)) {
121
118
  table = previousWord;
122
119
  }
123
- if( wordUpperCase !== CONS.ALIAS_KEYWORD ){
120
+ if (wordUpperCase !== CONS.ALIAS_KEYWORD) {
124
121
  previousWord = word;
125
122
  }
126
123
  });
127
- if( table ){ break; }
124
+ if (table) break;
128
125
  }
129
126
  return table;
130
127
  }
131
128
 
132
- function sqlHint(editor, options) {
129
+ CodeMirror.registerHelper("hint", "sql", function(editor, options) {
133
130
  tables = (options && options.tables) || {};
134
131
  keywords = keywords || getKeywords(editor);
135
132
  var cur = editor.getCursor();
136
- var token = editor.getTokenAt(cur), end = token.end;
137
133
  var result = [];
138
- var search = token.string.trim();
139
-
134
+ var token = editor.getTokenAt(cur), start, end, search;
135
+ if (token.string.match(/^[.\w@]\w*$/)) {
136
+ search = token.string;
137
+ start = token.start;
138
+ end = token.end;
139
+ } else {
140
+ start = end = cur.ch;
141
+ search = "";
142
+ }
140
143
  if (search.charAt(0) == ".") {
141
144
  columnCompletion(result, editor);
142
145
  if (!result.length) {
143
- while (token.start && search.charAt(0) == ".") {
146
+ while (start && search.charAt(0) == ".") {
144
147
  token = editor.getTokenAt(Pos(cur.line, token.start - 1));
148
+ start = token.start;
145
149
  search = token.string + search;
146
150
  }
147
- addMatches(result, search, tables,
148
- function(w) {return w;});
151
+ addMatches(result, search, tables, function(w) {return w;});
149
152
  }
150
153
  } else {
151
- addMatches(result, search, keywords,
152
- function(w) {return w.toUpperCase();});
153
- addMatches(result, search, tables,
154
- function(w) {return w;});
154
+ addMatches(result, search, tables, function(w) {return w;});
155
+ addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
155
156
  }
156
157
 
157
- return {
158
- list: result,
159
- from: Pos(cur.line, token.start),
160
- to: Pos(cur.line, end)
161
- };
162
- }
163
- CodeMirror.registerHelper("hint", "sql", sqlHint);
158
+ return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
159
+ });
164
160
  });