2 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
3 mod(require("../../lib/codemirror"));
4 else if (typeof define
== "function" && define
.amd
) // AMD
5 define(["../../lib/codemirror"], mod
);
6 else // Plain browser env
8 })(function(CodeMirror
) {
9 var DEFAULT_BRACKETS
= "()[]{}''\"\"";
10 var DEFAULT_EXPLODE_ON_ENTER
= "[]{}";
11 var SPACE_CHAR_REGEX
= /\s/;
13 CodeMirror
.defineOption("autoCloseBrackets", false, function(cm
, val
, old
) {
14 if (old
!= CodeMirror
.Init
&& old
)
15 cm
.removeKeyMap("autoCloseBrackets");
17 var pairs
= DEFAULT_BRACKETS
, explode
= DEFAULT_EXPLODE_ON_ENTER
;
18 if (typeof val
== "string") pairs
= val
;
19 else if (typeof val
== "object") {
20 if (val
.pairs
!= null) pairs
= val
.pairs
;
21 if (val
.explode
!= null) explode
= val
.explode
;
23 var map
= buildKeymap(pairs
);
24 if (explode
) map
.Enter
= buildExplodeHandler(explode
);
28 function charsAround(cm
, pos
) {
29 var str
= cm
.getRange(CodeMirror
.Pos(pos
.line
, pos
.ch
- 1),
30 CodeMirror
.Pos(pos
.line
, pos
.ch
+ 1));
31 return str
.length
== 2 ? str
: null;
34 function buildKeymap(pairs
) {
36 name
: "autoCloseBrackets",
37 Backspace: function(cm
) {
38 if (cm
.getOption("disableInput")) return CodeMirror
.Pass
;
39 var ranges
= cm
.listSelections();
40 for (var i
= 0; i
< ranges
.length
; i
++) {
41 if (!ranges
[i
].empty()) return CodeMirror
.Pass
;
42 var around
= charsAround(cm
, ranges
[i
].head
);
43 if (!around
|| pairs
.indexOf(around
) % 2 != 0) return CodeMirror
.Pass
;
45 for (var i
= ranges
.length
- 1; i
>= 0; i
--) {
46 var cur
= ranges
[i
].head
;
47 cm
.replaceRange("", CodeMirror
.Pos(cur
.line
, cur
.ch
- 1), CodeMirror
.Pos(cur
.line
, cur
.ch
+ 1));
51 var closingBrackets
= "";
52 for (var i
= 0; i
< pairs
.length
; i
+= 2) (function(left
, right
) {
53 if (left
!= right
) closingBrackets
+= right
;
54 map
["'" + left
+ "'"] = function(cm
) {
55 if (cm
.getOption("disableInput")) return CodeMirror
.Pass
;
56 var ranges
= cm
.listSelections(), type
, next
;
57 for (var i
= 0; i
< ranges
.length
; i
++) {
58 var range
= ranges
[i
], cur
= range
.head
, curType
;
59 if (left
== "'" && cm
.getTokenTypeAt(cur
) == "comment")
60 return CodeMirror
.Pass
;
61 var next
= cm
.getRange(cur
, CodeMirror
.Pos(cur
.line
, cur
.ch
+ 1));
64 else if (left
== right
&& next
== right
)
66 else if (left
== right
&& CodeMirror
.isWordChar(next
))
67 return CodeMirror
.Pass
;
68 else if (cm
.getLine(cur
.line
).length
== cur
.ch
|| closingBrackets
.indexOf(next
) >= 0 || SPACE_CHAR_REGEX
.test(next
))
71 return CodeMirror
.Pass
;
72 if (!type
) type
= curType
;
73 else if (type
!= curType
) return CodeMirror
.Pass
;
77 cm
.execCommand("goCharRight");
78 } else if (type
== "surround") {
79 var sels
= cm
.getSelections();
80 for (var i
= 0; i
< sels
.length
; i
++)
81 sels
[i
] = left
+ sels
[i
] + right
;
82 cm
.replaceSelections(sels
, "around");
83 } else if (type
== "both") {
84 cm
.replaceSelection(left
+ right
, null);
85 cm
.execCommand("goCharLeft");
88 if (left
!= right
) map
["'" + right
+ "'"] = function(cm
) {
89 var ranges
= cm
.listSelections();
90 for (var i
= 0; i
< ranges
.length
; i
++) {
91 var range
= ranges
[i
];
93 cm
.getRange(range
.head
, CodeMirror
.Pos(range
.head
.line
, range
.head
.ch
+ 1)) != right
)
94 return CodeMirror
.Pass
;
96 cm
.execCommand("goCharRight");
98 })(pairs
.charAt(i
), pairs
.charAt(i
+ 1));
102 function buildExplodeHandler(pairs
) {
103 return function(cm
) {
104 if (cm
.getOption("disableInput")) return CodeMirror
.Pass
;
105 var ranges
= cm
.listSelections();
106 for (var i
= 0; i
< ranges
.length
; i
++) {
107 if (!ranges
[i
].empty()) return CodeMirror
.Pass
;
108 var around
= charsAround(cm
, ranges
[i
].head
);
109 if (!around
|| pairs
.indexOf(around
) % 2 != 0) return CodeMirror
.Pass
;
111 cm
.operation(function() {
112 cm
.replaceSelection("\n\n", null);
113 cm
.execCommand("goCharLeft");
114 ranges
= cm
.listSelections();
115 for (var i
= 0; i
< ranges
.length
; i
++) {
116 var line
= ranges
[i
].head
.line
;
117 cm
.indentLine(line
, null, true);
118 cm
.indentLine(line
+ 1, null, true);