diff options
Diffstat (limited to 'imports/codemirror/lib/util/foldcode.js')
-rwxr-xr-x | imports/codemirror/lib/util/foldcode.js | 66 |
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 @@ | |||
1 | CodeMirror.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 | |||
27 | CodeMirror.newFoldFunction = function(rangeFinder, markText) { | ||
28 | var folded = []; | ||
29 | if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">▼</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 | }; | ||