codemirror-rails 4.4 → 4.5

Sign up to get free protection for your applications and to get access to all the features.
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
  });