codemirror-rails 2.36 → 3.00

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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();