codemirror-rails 2.36 → 3.00

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/lib/codemirror/rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/codemirror.js +3727 -2345
  3. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +2226 -825
  4. data/vendor/assets/javascripts/codemirror/modes/clike.js +23 -8
  5. data/vendor/assets/javascripts/codemirror/modes/clojure.js +4 -4
  6. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +1 -1
  7. data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +1 -1
  8. data/vendor/assets/javascripts/codemirror/modes/css.js +20 -3
  9. data/vendor/assets/javascripts/codemirror/modes/diff.js +2 -2
  10. data/vendor/assets/javascripts/codemirror/modes/ecl.js +192 -203
  11. data/vendor/assets/javascripts/codemirror/modes/erlang.js +1 -1
  12. data/vendor/assets/javascripts/codemirror/modes/gfm.js +1 -1
  13. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -6
  14. data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
  15. data/vendor/assets/javascripts/codemirror/modes/haskell.js +1 -1
  16. data/vendor/assets/javascripts/codemirror/modes/haxe.js +13 -13
  17. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +3 -3
  18. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/http.js +98 -0
  20. data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
  21. data/vendor/assets/javascripts/codemirror/modes/jinja2.js +1 -1
  22. data/vendor/assets/javascripts/codemirror/modes/markdown.js +7 -14
  23. data/vendor/assets/javascripts/codemirror/modes/mysql.js +2 -2
  24. data/vendor/assets/javascripts/codemirror/modes/ntriples.js +0 -2
  25. data/vendor/assets/javascripts/codemirror/modes/ocaml.js +1 -2
  26. data/vendor/assets/javascripts/codemirror/modes/pascal.js +2 -2
  27. data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
  28. data/vendor/assets/javascripts/codemirror/modes/php.js +5 -4
  29. data/vendor/assets/javascripts/codemirror/modes/pig.js +3 -4
  30. data/vendor/assets/javascripts/codemirror/modes/plsql.js +3 -4
  31. data/vendor/assets/javascripts/codemirror/modes/python.js +1 -1
  32. data/vendor/assets/javascripts/codemirror/modes/r.js +1 -1
  33. data/vendor/assets/javascripts/codemirror/modes/rpm-changes.js +1 -1
  34. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  35. data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -13
  36. data/vendor/assets/javascripts/codemirror/modes/ruby.js +1 -1
  37. data/vendor/assets/javascripts/codemirror/modes/rust.js +3 -3
  38. data/vendor/assets/javascripts/codemirror/modes/scheme.js +4 -4
  39. data/vendor/assets/javascripts/codemirror/modes/shell.js +1 -1
  40. data/vendor/assets/javascripts/codemirror/modes/sieve.js +1 -1
  41. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +2 -2
  42. data/vendor/assets/javascripts/codemirror/modes/smarty.js +1 -1
  43. data/vendor/assets/javascripts/codemirror/modes/sparql.js +2 -2
  44. data/vendor/assets/javascripts/codemirror/modes/stex.js +6 -13
  45. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +6 -37
  46. data/vendor/assets/javascripts/codemirror/modes/tiki.js +3 -3
  47. data/vendor/assets/javascripts/codemirror/modes/vb.js +3 -3
  48. data/vendor/assets/javascripts/codemirror/modes/velocity.js +2 -4
  49. data/vendor/assets/javascripts/codemirror/modes/verilog.js +182 -194
  50. data/vendor/assets/javascripts/codemirror/modes/xml.js +9 -5
  51. data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -4
  52. data/vendor/assets/javascripts/codemirror/utils/closetag.js +85 -164
  53. data/vendor/assets/javascripts/codemirror/utils/colorize.js +29 -0
  54. data/vendor/assets/javascripts/codemirror/utils/continuecomment.js +1 -1
  55. data/vendor/assets/javascripts/codemirror/utils/continuelist.js +28 -0
  56. data/vendor/assets/javascripts/codemirror/utils/dialog.js +21 -16
  57. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +59 -73
  58. data/vendor/assets/javascripts/codemirror/utils/formatting.js +43 -131
  59. data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +22 -19
  60. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +5 -3
  61. data/vendor/assets/javascripts/codemirror/utils/matchbrackets.js +63 -0
  62. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +18 -0
  63. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +3 -9
  64. data/vendor/assets/javascripts/codemirror/utils/runmode.js +19 -20
  65. data/vendor/assets/javascripts/codemirror/utils/search.js +6 -5
  66. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
  67. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +10 -10
  68. data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +2 -2
  69. data/vendor/assets/stylesheets/codemirror.css +169 -104
  70. data/vendor/assets/stylesheets/codemirror/themes/ambiance-mobile.css +1 -1
  71. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +7 -12
  72. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +3 -3
  73. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +3 -3
  74. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +3 -3
  75. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +4 -4
  76. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +3 -3
  77. data/vendor/assets/stylesheets/codemirror/themes/night.css +3 -3
  78. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +3 -3
  79. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +207 -0
  80. data/vendor/assets/stylesheets/codemirror/themes/twilight.css +4 -4
  81. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +3 -3
  82. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +3 -3
  83. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +12 -7
  84. metadata +16 -11
@@ -1,15 +1,15 @@
1
1
  // the tagRangeFinder function is
2
2
  // Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
3
3
  // released under the MIT license (../../LICENSE) like the rest of CodeMirror
4
- CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
4
+ CodeMirror.tagRangeFinder = function(cm, start) {
5
5
  var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
6
6
  var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
7
7
  var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
8
8
 
9
- var lineText = cm.getLine(line);
9
+ var lineText = cm.getLine(start.line);
10
10
  var found = false;
11
11
  var tag = null;
12
- var pos = 0;
12
+ var pos = start.ch;
13
13
  while (!found) {
14
14
  pos = lineText.indexOf("<", pos);
15
15
  if (-1 == pos) // no tag on line
@@ -18,28 +18,26 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
18
18
  pos++;
19
19
  continue;
20
20
  }
21
- // ok we weem to have a start tag
21
+ // ok we seem to have a start tag
22
22
  if (!lineText.substr(pos + 1).match(xmlNAMERegExp)) { // not a tag name...
23
23
  pos++;
24
24
  continue;
25
25
  }
26
26
  var gtPos = lineText.indexOf(">", pos + 1);
27
27
  if (-1 == gtPos) { // end of start tag not in line
28
- var l = line + 1;
28
+ var l = start.line + 1;
29
29
  var foundGt = false;
30
30
  var lastLine = cm.lineCount();
31
31
  while (l < lastLine && !foundGt) {
32
32
  var lt = cm.getLine(l);
33
- var gt = lt.indexOf(">");
34
- if (-1 != gt) { // found a >
33
+ gtPos = lt.indexOf(">");
34
+ if (-1 != gtPos) { // found a >
35
35
  foundGt = true;
36
- var slash = lt.lastIndexOf("/", gt);
37
- if (-1 != slash && slash < gt) {
38
- var str = lineText.substr(slash, gt - slash + 1);
39
- if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag
40
- if (hideEnd === true) l++;
41
- return l;
42
- }
36
+ var slash = lt.lastIndexOf("/", gtPos);
37
+ if (-1 != slash && slash < gtPos) {
38
+ var str = lineText.substr(slash, gtPos - slash + 1);
39
+ if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag
40
+ return;
43
41
  }
44
42
  }
45
43
  l++;
@@ -83,10 +81,10 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
83
81
 
84
82
  if (found) {
85
83
  var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\\s)|(\\<" + tag + "$)";
86
- var startTagRegExp = new RegExp(startTag, "g");
84
+ var startTagRegExp = new RegExp(startTag);
87
85
  var endTag = "</" + tag + ">";
88
86
  var depth = 1;
89
- var l = line + 1;
87
+ var l = start.line + 1;
90
88
  var lastLine = cm.lineCount();
91
89
  while (l < lastLine) {
92
90
  lineText = cm.getLine(l);
@@ -97,10 +95,8 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
97
95
  depth--;
98
96
  else
99
97
  depth++;
100
- if (!depth) {
101
- if (hideEnd === true) l++;
102
- return l;
103
- }
98
+ if (!depth) return {from: {line: start.line, ch: gtPos + 1},
99
+ to: {line: l, ch: match.index}};
104
100
  }
105
101
  }
106
102
  l++;
@@ -109,17 +105,18 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
109
105
  }
110
106
  };
111
107
 
112
- CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
113
- var lineText = cm.getLine(line), at = lineText.length, startChar, tokenType;
108
+ CodeMirror.braceRangeFinder = function(cm, start) {
109
+ var line = start.line, lineText = cm.getLine(line);
110
+ var at = lineText.length, startChar, tokenType;
114
111
  for (;;) {
115
112
  var found = lineText.lastIndexOf("{", at);
116
- if (found < 0) break;
117
- tokenType = cm.getTokenAt({line: line, ch: found}).className;
113
+ if (found < start.ch) break;
114
+ tokenType = cm.getTokenAt({line: line, ch: found}).type;
118
115
  if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
119
116
  at = found - 1;
120
117
  }
121
118
  if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
122
- var count = 1, lastLine = cm.lineCount(), end;
119
+ var count = 1, lastLine = cm.lineCount(), end, endCh;
123
120
  outer: for (var i = line + 1; i < lastLine; ++i) {
124
121
  var text = cm.getLine(i), pos = 0;
125
122
  for (;;) {
@@ -128,69 +125,58 @@ CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
128
125
  if (nextClose < 0) nextClose = text.length;
129
126
  pos = Math.min(nextOpen, nextClose);
130
127
  if (pos == text.length) break;
131
- if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
128
+ if (cm.getTokenAt({line: i, ch: pos + 1}).type == tokenType) {
132
129
  if (pos == nextOpen) ++count;
133
- else if (!--count) { end = i; break outer; }
130
+ else if (!--count) { end = i; endCh = pos; break outer; }
134
131
  }
135
132
  ++pos;
136
133
  }
137
134
  }
138
135
  if (end == null || end == line + 1) return;
139
- if (hideEnd === true) end++;
140
- return end;
136
+ return {from: {line: line, ch: startChar + 1},
137
+ to: {line: end, ch: endCh}};
141
138
  };
142
139
 
143
- CodeMirror.indentRangeFinder = function(cm, line) {
144
- var tabSize = cm.getOption("tabSize");
145
- var myIndent = cm.getLineHandle(line).indentation(tabSize), last;
146
- for (var i = line + 1, end = cm.lineCount(); i < end; ++i) {
147
- var handle = cm.getLineHandle(i);
148
- if (!/^\s*$/.test(handle.text)) {
149
- if (handle.indentation(tabSize) <= myIndent) break;
150
- last = i;
151
- }
140
+ CodeMirror.indentRangeFinder = function(cm, start) {
141
+ var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
142
+ var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
143
+ for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
144
+ var curLine = cm.getLine(i);
145
+ if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent)
146
+ return {from: {line: start.line, ch: firstLine.length},
147
+ to: {line: i, ch: curLine.length}};
152
148
  }
153
- if (!last) return null;
154
- return last + 1;
155
149
  };
156
150
 
157
- CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) {
158
- var folded = [];
159
- if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
160
-
161
- function isFolded(cm, n) {
162
- for (var i = 0; i < folded.length; ++i) {
163
- var start = cm.lineInfo(folded[i].start);
164
- if (!start) folded.splice(i--, 1);
165
- else if (start.line == n) return {pos: i, region: folded[i]};
166
- }
151
+ CodeMirror.newFoldFunction = function(rangeFinder, widget) {
152
+ if (widget == null) widget = "\u2194";
153
+ if (typeof widget == "string") {
154
+ var text = document.createTextNode(widget);
155
+ widget = document.createElement("span");
156
+ widget.appendChild(text);
157
+ widget.className = "CodeMirror-foldmarker";
167
158
  }
168
159
 
169
- function expand(cm, region) {
170
- cm.clearMarker(region.start);
171
- for (var i = 0; i < region.hidden.length; ++i)
172
- cm.showLine(region.hidden[i]);
173
- }
160
+ return function(cm, pos) {
161
+ if (typeof pos == "number") pos = {line: pos, ch: 0};
162
+ var range = rangeFinder(cm, pos);
163
+ if (!range) return;
174
164
 
175
- return function(cm, line) {
176
- cm.operation(function() {
177
- var known = isFolded(cm, line);
178
- if (known) {
179
- folded.splice(known.pos, 1);
180
- expand(cm, known.region);
181
- } else {
182
- var end = rangeFinder(cm, line, hideEnd);
183
- if (end == null) return;
184
- var hidden = [];
185
- for (var i = line + 1; i < end; ++i) {
186
- var handle = cm.hideLine(i);
187
- if (handle) hidden.push(handle);
188
- }
189
- var first = cm.setMarker(line, markText);
190
- var region = {start: first, hidden: hidden};
191
- cm.onDeleteLine(first, function() { expand(cm, region); });
192
- folded.push(region);
165
+ var present = cm.findMarksAt(range.from), cleared = 0;
166
+ for (var i = 0; i < present.length; ++i) {
167
+ if (present[i].__isFold) {
168
+ ++cleared;
169
+ present[i].clear();
193
170
  }
171
+ }
172
+ if (cleared) return;
173
+
174
+ var myWidget = widget.cloneNode(true);
175
+ CodeMirror.on(myWidget, "mousedown", function() {myRange.clear();});
176
+ var myRange = cm.markText(range.from, range.to, {
177
+ replacedWith: myWidget,
178
+ clearOnEnter: true,
179
+ __isFold: true
194
180
  });
195
181
  };
196
182
  };
@@ -1,138 +1,39 @@
1
- // ============== Formatting extensions ============================
2
1
  (function() {
3
- // Define extensions for a few modes
2
+
4
3
  CodeMirror.extendMode("css", {
5
4
  commentStart: "/*",
6
5
  commentEnd: "*/",
7
- wordWrapChars: [";", "\\{", "\\}"],
8
- autoFormatLineBreaks: function (text) {
9
- return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
6
+ newlineAfterToken: function(_type, content) {
7
+ return /^[;{}]$/.test(content);
10
8
  }
11
9
  });
12
10
 
13
- function jsNonBreakableBlocks(text) {
14
- var nonBreakableRegexes = [/for\s*?\((.*?)\)/,
15
- /\"(.*?)(\"|$)/,
16
- /\'(.*?)(\'|$)/,
17
- /\/\*(.*?)(\*\/|$)/,
18
- /\/\/.*/];
19
- var nonBreakableBlocks = [];
20
- for (var i = 0; i < nonBreakableRegexes.length; i++) {
21
- var curPos = 0;
22
- while (curPos < text.length) {
23
- var m = text.substr(curPos).match(nonBreakableRegexes[i]);
24
- if (m != null) {
25
- nonBreakableBlocks.push({
26
- start: curPos + m.index,
27
- end: curPos + m.index + m[0].length
28
- });
29
- curPos += m.index + Math.max(1, m[0].length);
30
- }
31
- else { // No more matches
32
- break;
33
- }
34
- }
35
- }
36
- nonBreakableBlocks.sort(function (a, b) {
37
- return a.start - b.start;
38
- });
39
-
40
- return nonBreakableBlocks;
41
- }
42
-
43
11
  CodeMirror.extendMode("javascript", {
44
12
  commentStart: "/*",
45
13
  commentEnd: "*/",
46
- wordWrapChars: [";", "\\{", "\\}"],
47
-
48
- autoFormatLineBreaks: function (text) {
49
- var curPos = 0;
50
- var split = this.jsonMode ? function(str) {
51
- return str.replace(/([,{])/g, "$1\n").replace(/}/g, "\n}");
52
- } : function(str) {
53
- return str.replace(/(;|\{|\})([^\r\n;])/g, "$1\n$2");
54
- };
55
- var nonBreakableBlocks = jsNonBreakableBlocks(text), res = "";
56
- if (nonBreakableBlocks != null) {
57
- for (var i = 0; i < nonBreakableBlocks.length; i++) {
58
- if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
59
- res += split(text.substring(curPos, nonBreakableBlocks[i].start));
60
- curPos = nonBreakableBlocks[i].start;
61
- }
62
- if (nonBreakableBlocks[i].start <= curPos
63
- && nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
64
- res += text.substring(curPos, nonBreakableBlocks[i].end);
65
- curPos = nonBreakableBlocks[i].end;
66
- }
67
- }
68
- if (curPos < text.length)
69
- res += split(text.substr(curPos));
14
+ // FIXME semicolons inside of for
15
+ newlineAfterToken: function(_type, content, textAfter, state) {
16
+ if (this.jsonMode) {
17
+ return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
70
18
  } else {
71
- res = split(text);
19
+ if (content == ";" && state.lexical && state.lexical.type == ")") return false;
20
+ return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
72
21
  }
73
- return res.replace(/^\n*|\n*$/, "");
74
22
  }
75
23
  });
76
24
 
77
25
  CodeMirror.extendMode("xml", {
78
26
  commentStart: "<!--",
79
27
  commentEnd: "-->",
80
- wordWrapChars: [">"],
81
-
82
- autoFormatLineBreaks: function (text) {
83
- var lines = text.split("\n");
84
- var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
85
- var reOpenBrackets = new RegExp("<", "g");
86
- var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
87
- for (var i = 0; i < lines.length; i++) {
88
- var mToProcess = lines[i].match(reProcessedPortion);
89
- if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
90
- lines[i] = mToProcess[1]
91
- + mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
92
- + mToProcess[3];
93
- continue;
94
- }
95
- }
96
- return lines.join("\n");
28
+ newlineAfterToken: function(type, content, textAfter) {
29
+ return type == "tag" && />$/.test(content) || /^</.test(textAfter);
97
30
  }
98
31
  });
99
32
 
100
- function localModeAt(cm, pos) {
101
- return CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(pos).state).mode;
102
- }
103
-
104
- function enumerateModesBetween(cm, line, start, end) {
105
- var outer = cm.getMode(), text = cm.getLine(line);
106
- if (end == null) end = text.length;
107
- if (!outer.innerMode) return [{from: start, to: end, mode: outer}];
108
- var state = cm.getTokenAt({line: line, ch: start}).state;
109
- var mode = CodeMirror.innerMode(outer, state).mode;
110
- var found = [], stream = new CodeMirror.StringStream(text);
111
- stream.pos = stream.start = start;
112
- for (;;) {
113
- outer.token(stream, state);
114
- var curMode = CodeMirror.innerMode(outer, state).mode;
115
- if (curMode != mode) {
116
- var cut = stream.start;
117
- // Crappy heuristic to deal with the fact that a change in
118
- // mode can occur both at the end and the start of a token,
119
- // and we don't know which it was.
120
- if (mode.name == "xml" && text.charAt(stream.pos - 1) == ">") cut = stream.pos;
121
- found.push({from: start, to: cut, mode: mode});
122
- start = cut;
123
- mode = curMode;
124
- }
125
- if (stream.pos >= end) break;
126
- stream.start = stream.pos;
127
- }
128
- if (start < end) found.push({from: start, to: end, mode: mode});
129
- return found;
130
- }
131
-
132
33
  // Comment/uncomment the specified range
133
34
  CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
134
- var curMode = localModeAt(this, from), cm = this;
135
- this.operation(function() {
35
+ var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
36
+ cm.operation(function() {
136
37
  if (isComment) { // Comment range
137
38
  cm.replaceRange(curMode.commentEnd, to);
138
39
  cm.replaceRange(curMode.commentStart, from);
@@ -168,27 +69,38 @@
168
69
  // Applies automatic formatting to the specified range
169
70
  CodeMirror.defineExtension("autoFormatRange", function (from, to) {
170
71
  var cm = this;
171
- cm.operation(function () {
172
- for (var cur = from.line, end = to.line; cur <= end; ++cur) {
173
- var f = {line: cur, ch: cur == from.line ? from.ch : 0};
174
- var t = {line: cur, ch: cur == end ? to.ch : null};
175
- var modes = enumerateModesBetween(cm, cur, f.ch, t.ch), mangled = "";
176
- var text = cm.getRange(f, t);
177
- for (var i = 0; i < modes.length; ++i) {
178
- var part = modes.length > 1 ? text.slice(modes[i].from, modes[i].to) : text;
179
- if (mangled) mangled += "\n";
180
- if (modes[i].mode.autoFormatLineBreaks) {
181
- mangled += modes[i].mode.autoFormatLineBreaks(part);
182
- } else mangled += text;
183
- }
184
- if (mangled != text) {
185
- for (var count = 0, pos = mangled.indexOf("\n"); pos != -1; pos = mangled.indexOf("\n", pos + 1), ++count) {}
186
- cm.replaceRange(mangled, f, t);
187
- cur += count;
188
- end += count;
72
+ var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
73
+ var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
74
+ var tabSize = cm.getOption("tabSize");
75
+
76
+ var out = "", lines = 0, atSol = from.ch == 0;
77
+ function newline() {
78
+ out += "\n";
79
+ atSol = true;
80
+ ++lines;
81
+ }
82
+
83
+ for (var i = 0; i < text.length; ++i) {
84
+ var stream = new CodeMirror.StringStream(text[i], tabSize);
85
+ while (!stream.eol()) {
86
+ var inner = CodeMirror.innerMode(outer, state);
87
+ var style = outer.token(stream, state), cur = stream.current();
88
+ stream.start = stream.pos;
89
+ if (!atSol || /\S/.test(cur)) {
90
+ out += cur;
91
+ atSol = false;
189
92
  }
93
+ if (!atSol && inner.mode.newlineAfterToken &&
94
+ inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
95
+ newline();
190
96
  }
191
- for (var cur = from.line + 1; cur <= end; ++cur)
97
+ if (!stream.pos && outer.blankLine) outer.blankLine(state);
98
+ if (!atSol) newline();
99
+ }
100
+
101
+ cm.operation(function () {
102
+ cm.replaceRange(out, from, to);
103
+ for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
192
104
  cm.indentLine(cur, "smart");
193
105
  cm.setSelection(from, cm.getCursor(false));
194
106
  });
@@ -16,16 +16,16 @@
16
16
  return arr.indexOf(item) != -1;
17
17
  }
18
18
 
19
- function scriptHint(editor, keywords, getToken) {
19
+ function scriptHint(editor, keywords, getToken, options) {
20
20
  // Find the token at the cursor
21
21
  var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
22
22
  // If it's not a 'word-style' token, ignore the token.
23
23
  if (!/^[\w$_]*$/.test(token.string)) {
24
24
  token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
25
- className: token.string == "." ? "property" : null};
25
+ type: token.string == "." ? "property" : null};
26
26
  }
27
27
  // If it is a property, find out what it is a property of.
28
- while (tprop.className == "property") {
28
+ while (tprop.type == "property") {
29
29
  tprop = getToken(editor, {line: cur.line, ch: tprop.start});
30
30
  if (tprop.string != ".") return;
31
31
  tprop = getToken(editor, {line: cur.line, ch: tprop.start});
@@ -40,21 +40,22 @@
40
40
  }
41
41
  } while (level > 0);
42
42
  tprop = getToken(editor, {line: cur.line, ch: tprop.start});
43
- if (tprop.className == 'variable')
44
- tprop.className = 'function';
45
- else return; // no clue
43
+ if (tprop.type == 'variable')
44
+ tprop.type = 'function';
45
+ else return; // no clue
46
46
  }
47
47
  if (!context) var context = [];
48
48
  context.push(tprop);
49
49
  }
50
- return {list: getCompletions(token, context, keywords),
50
+ return {list: getCompletions(token, context, keywords, options),
51
51
  from: {line: cur.line, ch: token.start},
52
52
  to: {line: cur.line, ch: token.end}};
53
53
  }
54
54
 
55
- CodeMirror.javascriptHint = function(editor) {
55
+ CodeMirror.javascriptHint = function(editor, options) {
56
56
  return scriptHint(editor, javascriptKeywords,
57
- function (e, cur) {return e.getTokenAt(cur);});
57
+ function (e, cur) {return e.getTokenAt(cur);},
58
+ options);
58
59
  };
59
60
 
60
61
  function getCoffeeScriptToken(editor, cur) {
@@ -65,18 +66,18 @@
65
66
  if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
66
67
  token.end = token.start;
67
68
  token.string = '.';
68
- token.className = "property";
69
+ token.type = "property";
69
70
  }
70
71
  else if (/^\.[\w$_]*$/.test(token.string)) {
71
- token.className = "property";
72
+ token.type = "property";
72
73
  token.start++;
73
74
  token.string = token.string.replace(/\./, '');
74
75
  }
75
76
  return token;
76
77
  }
77
78
 
78
- CodeMirror.coffeescriptHint = function(editor) {
79
- return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
79
+ CodeMirror.coffeescriptHint = function(editor, options) {
80
+ return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
80
81
  };
81
82
 
82
83
  var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
@@ -89,7 +90,7 @@
89
90
  var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
90
91
  "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
91
92
 
92
- function getCompletions(token, context, keywords) {
93
+ function getCompletions(token, context, keywords, options) {
93
94
  var found = [], start = token.string;
94
95
  function maybeAdd(str) {
95
96
  if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
@@ -105,13 +106,15 @@
105
106
  // If this is a property, see if it belongs to some object we can
106
107
  // find in the current environment.
107
108
  var obj = context.pop(), base;
108
- if (obj.className == "variable")
109
- base = window[obj.string];
110
- else if (obj.className == "string")
109
+ if (obj.type == "variable") {
110
+ if (options && options.additionalContext)
111
+ base = options.additionalContext[obj.string];
112
+ base = base || window[obj.string];
113
+ } else if (obj.type == "string") {
111
114
  base = "";
112
- else if (obj.className == "atom")
115
+ } else if (obj.type == "atom") {
113
116
  base = 1;
114
- else if (obj.className == "function") {
117
+ } else if (obj.type == "function") {
115
118
  if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
116
119
  (typeof window.jQuery == 'function'))
117
120
  base = window.jQuery();