Skip to content

Commit 68b2994

Browse files
committed
Split folding functions into their own files
1 parent 478119f commit 68b2994

File tree

7 files changed

+117
-114
lines changed

7 files changed

+117
-114
lines changed

addon/fold/brace-fold.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
CodeMirror.braceRangeFinder = function(cm, start) {
2+
var line = start.line, lineText = cm.getLine(line);
3+
var at = lineText.length, startChar, tokenType;
4+
for (;;) {
5+
var found = lineText.lastIndexOf("{", at);
6+
if (found < start.ch) break;
7+
tokenType = cm.getTokenAt(CodeMirror.Pos(line, found + 1)).type;
8+
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
9+
at = found - 1;
10+
}
11+
if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
12+
var count = 1, lastLine = cm.lineCount(), end, endCh;
13+
outer: for (var i = line + 1; i < lastLine; ++i) {
14+
var text = cm.getLine(i), pos = 0;
15+
for (;;) {
16+
var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
17+
if (nextOpen < 0) nextOpen = text.length;
18+
if (nextClose < 0) nextClose = text.length;
19+
pos = Math.min(nextOpen, nextClose);
20+
if (pos == text.length) break;
21+
if (cm.getTokenAt(CodeMirror.Pos(i, pos + 1)).type == tokenType) {
22+
if (pos == nextOpen) ++count;
23+
else if (!--count) { end = i; endCh = pos; break outer; }
24+
}
25+
++pos;
26+
}
27+
}
28+
if (end == null || end == line + 1) return;
29+
return {from: CodeMirror.Pos(line, startChar + 1),
30+
to: CodeMirror.Pos(end, endCh)};
31+
};

addon/fold/foldcode.js

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,3 @@
1-
CodeMirror.tagRangeFinder = (function() {
2-
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";
3-
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
4-
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
5-
6-
return function(cm, start) {
7-
var line = start.line, ch = start.ch, lineText = cm.getLine(line);
8-
9-
function nextLine() {
10-
if (line >= cm.lastLine()) return;
11-
ch = 0;
12-
lineText = cm.getLine(++line);
13-
return true;
14-
}
15-
function toTagEnd() {
16-
for (;;) {
17-
var gt = lineText.indexOf(">", ch);
18-
if (gt == -1) { if (nextLine()) continue; else return; }
19-
var lastSlash = lineText.lastIndexOf("/", gt);
20-
var selfClose = lastSlash > -1 && /^\s*$/.test(lineText.slice(lastSlash + 1, gt));
21-
ch = gt + 1;
22-
return selfClose ? "selfClose" : "regular";
23-
}
24-
}
25-
function toNextTag() {
26-
for (;;) {
27-
xmlTagStart.lastIndex = ch;
28-
var found = xmlTagStart.exec(lineText);
29-
if (!found) { if (nextLine()) continue; else return; }
30-
ch = found.index + found[0].length;
31-
return found;
32-
}
33-
}
34-
35-
var stack = [], startCh;
36-
for (;;) {
37-
var openTag = toNextTag(), end;
38-
if (!openTag || line != start.line || !(end = toTagEnd())) return;
39-
if (!openTag[1] && end != "selfClose") {
40-
stack.push(openTag[2]);
41-
startCh = ch;
42-
break;
43-
}
44-
}
45-
46-
for (;;) {
47-
var next = toNextTag(), end, tagLine = line, tagCh = ch - (next ? next[0].length : 0);
48-
if (!next || !(end = toTagEnd())) return;
49-
if (end == "selfClose") continue;
50-
if (next[1]) { // closing tag
51-
for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
52-
stack.length = i;
53-
break;
54-
}
55-
if (!stack.length) return {
56-
from: CodeMirror.Pos(start.line, startCh),
57-
to: CodeMirror.Pos(tagLine, tagCh)
58-
};
59-
} else { // opening tag
60-
stack.push(next[2]);
61-
}
62-
}
63-
};
64-
})();
65-
66-
CodeMirror.braceRangeFinder = function(cm, start) {
67-
var line = start.line, lineText = cm.getLine(line);
68-
var at = lineText.length, startChar, tokenType;
69-
for (;;) {
70-
var found = lineText.lastIndexOf("{", at);
71-
if (found < start.ch) break;
72-
tokenType = cm.getTokenAt(CodeMirror.Pos(line, found + 1)).type;
73-
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
74-
at = found - 1;
75-
}
76-
if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
77-
var count = 1, lastLine = cm.lineCount(), end, endCh;
78-
outer: for (var i = line + 1; i < lastLine; ++i) {
79-
var text = cm.getLine(i), pos = 0;
80-
for (;;) {
81-
var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
82-
if (nextOpen < 0) nextOpen = text.length;
83-
if (nextClose < 0) nextClose = text.length;
84-
pos = Math.min(nextOpen, nextClose);
85-
if (pos == text.length) break;
86-
if (cm.getTokenAt(CodeMirror.Pos(i, pos + 1)).type == tokenType) {
87-
if (pos == nextOpen) ++count;
88-
else if (!--count) { end = i; endCh = pos; break outer; }
89-
}
90-
++pos;
91-
}
92-
}
93-
if (end == null || end == line + 1) return;
94-
return {from: CodeMirror.Pos(line, startChar + 1),
95-
to: CodeMirror.Pos(end, endCh)};
96-
};
97-
98-
CodeMirror.indentRangeFinder = function(cm, start) {
99-
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
100-
var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
101-
for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
102-
var curLine = cm.getLine(i);
103-
if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent &&
104-
CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent)
105-
return {from: CodeMirror.Pos(start.line, firstLine.length),
106-
to: CodeMirror.Pos(i, curLine.length)};
107-
}
108-
};
109-
1101
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
1112
if (widget == null) widget = "\u2194";
1123
if (typeof widget == "string") {

addon/fold/indent-fold.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CodeMirror.indentRangeFinder = function(cm, start) {
2+
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
3+
var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
4+
for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
5+
var curLine = cm.getLine(i);
6+
if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent &&
7+
CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent)
8+
return {from: CodeMirror.Pos(start.line, firstLine.length),
9+
to: CodeMirror.Pos(i, curLine.length)};
10+
}
11+
};

addon/fold/xml-fold.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
CodeMirror.tagRangeFinder = (function() {
2+
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";
3+
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
4+
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
5+
6+
return function(cm, start) {
7+
var line = start.line, ch = start.ch, lineText = cm.getLine(line);
8+
9+
function nextLine() {
10+
if (line >= cm.lastLine()) return;
11+
ch = 0;
12+
lineText = cm.getLine(++line);
13+
return true;
14+
}
15+
function toTagEnd() {
16+
for (;;) {
17+
var gt = lineText.indexOf(">", ch);
18+
if (gt == -1) { if (nextLine()) continue; else return; }
19+
var lastSlash = lineText.lastIndexOf("/", gt);
20+
var selfClose = lastSlash > -1 && /^\s*$/.test(lineText.slice(lastSlash + 1, gt));
21+
ch = gt + 1;
22+
return selfClose ? "selfClose" : "regular";
23+
}
24+
}
25+
function toNextTag() {
26+
for (;;) {
27+
xmlTagStart.lastIndex = ch;
28+
var found = xmlTagStart.exec(lineText);
29+
if (!found) { if (nextLine()) continue; else return; }
30+
ch = found.index + found[0].length;
31+
return found;
32+
}
33+
}
34+
35+
var stack = [], startCh;
36+
for (;;) {
37+
var openTag = toNextTag(), end;
38+
if (!openTag || line != start.line || !(end = toTagEnd())) return;
39+
if (!openTag[1] && end != "selfClose") {
40+
stack.push(openTag[2]);
41+
startCh = ch;
42+
break;
43+
}
44+
}
45+
46+
for (;;) {
47+
var next = toNextTag(), end, tagLine = line, tagCh = ch - (next ? next[0].length : 0);
48+
if (!next || !(end = toTagEnd())) return;
49+
if (end == "selfClose") continue;
50+
if (next[1]) { // closing tag
51+
for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
52+
stack.length = i;
53+
break;
54+
}
55+
if (!stack.length) return {
56+
from: CodeMirror.Pos(start.line, startCh),
57+
to: CodeMirror.Pos(tagLine, tagCh)
58+
};
59+
} else { // opening tag
60+
stack.push(next[2]);
61+
}
62+
}
63+
};
64+
})();

demo/folding.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<link rel="stylesheet" href="../lib/codemirror.css">
77
<script src="../lib/codemirror.js"></script>
88
<script src="../addon/fold/foldcode.js"></script>
9+
<script src="../addon/fold/brace-fold.js"></script>
10+
<script src="../addon/fold/xml-fold.js"></script>
911
<script src="../mode/javascript/javascript.js"></script>
1012
<script src="../mode/xml/xml.js"></script>
1113
<link rel="stylesheet" href="../doc/docs.css">
@@ -27,7 +29,7 @@ <h1>CodeMirror: Code Folding Demo</h1>
2729
<p>Demonstration of code folding using the code
2830
in <a href="../addon/fold/foldcode.js"><code>foldcode.js</code></a>.
2931
Press ctrl-q or click on the gutter to fold a block, again
30-
to unfold.<br>Try the <a href="collapserange.html">Range Colapse demo</a> as well.</p>
32+
to unfold.</p>
3133
<form>
3234
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br><textarea id="code" name="code"></textarea></div>
3335
<div style="max-width: 50em">HTML:<br><textarea id="code-html" name="code-html"></textarea></div>

doc/compress.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMi
139139
<option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
140140
<option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
141141
<option value="http://codemirror.net/addon/fold/foldcode.js">foldcode.js</option>
142+
<option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
143+
<option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
144+
<option value="http://codemirror.net/addon/fold/indent-fold.js">indent-fold.js</option>
142145
<option value="http://codemirror.net/addon/fold/collapserange.js">collapserange.js</option>
143146
<option value="http://codemirror.net/addon/hint/simple-hint.js">simple-hint.js</option>
144147
<option value="http://codemirror.net/addon/hint/javascript-hint.js">javascript-hint.js</option>

doc/manual.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,10 +1454,11 @@ <h2 id="addons">Add-ons</h2>
14541454
a CodeMirror instance and a line number, attempt to fold or
14551455
unfold the block starting at the given line. A range-finder is a
14561456
language-specific function that also takes an instance and a
1457-
line number, and returns an range to be folded, or null if
1458-
no block is started on that line. This file
1459-
provides <code>CodeMirror.braceRangeFinder</code>, which finds
1460-
blocks in brace languages (JavaScript, C, Java,
1457+
line number, and returns an range to be folded, or null if no
1458+
block is started on that line. There are files in
1459+
the <a href="../addon/fold/"><code>addon/fold/</code></a>
1460+
directory providing <code>CodeMirror.braceRangeFinder</code>,
1461+
which finds blocks in brace languages (JavaScript, C, Java,
14611462
etc), <code>CodeMirror.indentRangeFinder</code>, for languages
14621463
where indentation determines block structure (Python, Haskell),
14631464
and <code>CodeMirror.tagRangeFinder</code>, for XML-style

0 commit comments

Comments
 (0)