aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/lib/util/foldcode.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/lib/util/foldcode.js')
-rwxr-xr-ximports/codemirror/lib/util/foldcode.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/imports/codemirror/lib/util/foldcode.js b/imports/codemirror/lib/util/foldcode.js
new file mode 100755
index 00000000..18957792
--- /dev/null
+++ b/imports/codemirror/lib/util/foldcode.js
@@ -0,0 +1,66 @@
1CodeMirror.braceRangeFinder = function(cm, line) {
2 var lineText = cm.getLine(line);
3 var startChar = lineText.lastIndexOf("{");
4 if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
5 var tokenType = cm.getTokenAt({line: line, ch: startChar}).className;
6 var count = 1, lastLine = cm.lineCount(), end;
7 outer: for (var i = line + 1; i < lastLine; ++i) {
8 var text = cm.getLine(i), pos = 0;
9 for (;;) {
10 var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
11 if (nextOpen < 0) nextOpen = text.length;
12 if (nextClose < 0) nextClose = text.length;
13 pos = Math.min(nextOpen, nextClose);
14 if (pos == text.length) break;
15 if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
16 if (pos == nextOpen) ++count;
17 else if (!--count) { end = i; break outer; }
18 }
19 ++pos;
20 }
21 }
22 if (end == null || end == line + 1) return;
23 return end;
24};
25
26
27CodeMirror.newFoldFunction = function(rangeFinder, markText) {
28 var folded = [];
29 if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
30
31 function isFolded(cm, n) {
32 for (var i = 0; i < folded.length; ++i) {
33 var start = cm.lineInfo(folded[i].start);
34 if (!start) folded.splice(i--, 1);
35 else if (start.line == n) return {pos: i, region: folded[i]};
36 }
37 }
38
39 function expand(cm, region) {
40 cm.clearMarker(region.start);
41 for (var i = 0; i < region.hidden.length; ++i)
42 cm.showLine(region.hidden[i]);
43 }
44
45 return function(cm, line) {
46 cm.operation(function() {
47 var known = isFolded(cm, line);
48 if (known) {
49 folded.splice(known.pos, 1);
50 expand(cm, known.region);
51 } else {
52 var end = rangeFinder(cm, line);
53 if (end == null) return;
54 var hidden = [];
55 for (var i = line + 1; i < end; ++i) {
56 var handle = cm.hideLine(i);
57 if (handle) hidden.push(handle);
58 }
59 var first = cm.setMarker(line, markText);
60 var region = {start: first, hidden: hidden};
61 cm.onDeleteLine(first, function() { expand(cm, region); });
62 folded.push(region);
63 }
64 });
65 };
66};