Skip to content

Commit 04323d0

Browse files
committed
[brace-fold addon] Add a brace-paren folding helper
Closes codemirror#6868
1 parent 42917b3 commit 04323d0

File tree

3 files changed

+53
-42
lines changed

3 files changed

+53
-42
lines changed

addon/fold/brace-fold.js

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,58 +11,67 @@
1111
})(function(CodeMirror) {
1212
"use strict";
1313

14-
CodeMirror.registerHelper("fold", "brace", function(cm, start) {
15-
var line = start.line, lineText = cm.getLine(line);
14+
function bracketFolding(pairs) {
15+
return function(cm, start) {
16+
var line = start.line, lineText = cm.getLine(line);
1617

17-
function findOpening(openCh) {
18-
var tokenType;
19-
for (var at = start.ch, pass = 0;;) {
20-
var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
21-
if (found == -1) {
22-
if (pass == 1) break;
23-
pass = 1;
24-
at = lineText.length;
25-
continue;
18+
function findOpening(pair) {
19+
var tokenType;
20+
for (var at = start.ch, pass = 0;;) {
21+
var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1);
22+
if (found == -1) {
23+
if (pass == 1) break;
24+
pass = 1;
25+
at = lineText.length;
26+
continue;
27+
}
28+
if (pass == 1 && found < start.ch) break;
29+
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
30+
if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair};
31+
at = found - 1;
2632
}
27-
if (pass == 1 && found < start.ch) break;
28-
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
29-
if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType};
30-
at = found - 1;
3133
}
32-
}
3334

34-
function findRange(startToken, endToken, found) {
35-
var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
36-
outer: for (var i = line; i <= lastLine; ++i) {
37-
var text = cm.getLine(i), pos = i == line ? startCh : 0;
38-
for (;;) {
39-
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
40-
if (nextOpen < 0) nextOpen = text.length;
41-
if (nextClose < 0) nextClose = text.length;
42-
pos = Math.min(nextOpen, nextClose);
43-
if (pos == text.length) break;
44-
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
45-
if (pos == nextOpen) ++count;
46-
else if (!--count) { end = i; endCh = pos; break outer; }
35+
function findRange(found) {
36+
var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
37+
outer: for (var i = line; i <= lastLine; ++i) {
38+
var text = cm.getLine(i), pos = i == line ? startCh : 0;
39+
for (;;) {
40+
var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos);
41+
if (nextOpen < 0) nextOpen = text.length;
42+
if (nextClose < 0) nextClose = text.length;
43+
pos = Math.min(nextOpen, nextClose);
44+
if (pos == text.length) break;
45+
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
46+
if (pos == nextOpen) ++count;
47+
else if (!--count) { end = i; endCh = pos; break outer; }
48+
}
49+
++pos;
4750
}
48-
++pos;
4951
}
50-
}
5152

52-
if (end == null || line == end) return null
53-
return {from: CodeMirror.Pos(line, startCh),
54-
to: CodeMirror.Pos(end, endCh)};
55-
}
53+
if (end == null || line == end) return null
54+
return {from: CodeMirror.Pos(line, startCh),
55+
to: CodeMirror.Pos(end, endCh)};
56+
}
5657

57-
var startBrace = findOpening("{"), startBracket = findOpening("[")
58-
if (startBrace && (!startBracket || startBracket.ch > startBrace.ch)) {
59-
return findRange("{", "}", startBrace) || (startBracket && findRange("[", "]", startBracket))
60-
} else if (startBracket) {
61-
return findRange("[", "]", startBracket) || (startBrace && findRange("{", "}", startBrace))
62-
} else {
58+
var found = []
59+
for (var i = 0; i < pairs.length; i++) {
60+
var open = findOpening(pairs[i])
61+
if (open) found.push(open)
62+
}
63+
found.sort(function(a, b) { return a.ch - b.ch })
64+
for (var i = 0; i < found.length; i++) {
65+
var range = findRange(found[i])
66+
if (range) return range
67+
}
6368
return null
6469
}
65-
});
70+
}
71+
72+
CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]]));
73+
74+
CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]]));
6675

6776
CodeMirror.registerHelper("fold", "import", function(cm, start) {
6877
function hasImport(line) {

mode/commonlisp/commonlisp.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ CodeMirror.defineMode("commonlisp", function (config) {
114114

115115
closeBrackets: {pairs: "()[]{}\"\""},
116116
lineComment: ";;",
117+
fold: "brace-paren",
117118
blockCommentStart: "#|",
118119
blockCommentEnd: "|#"
119120
};

mode/scheme/scheme.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ CodeMirror.defineMode("scheme", function () {
273273
return state.indentStack.indent;
274274
},
275275

276+
fold: "brace-paren",
276277
closeBrackets: {pairs: "()[]{}\"\""},
277278
lineComment: ";;"
278279
};

0 commit comments

Comments
 (0)