|
1 (function(mod) { |
|
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 |
|
7 mod(CodeMirror); |
|
8 })(function(CodeMirror) { |
|
9 "use strict"; |
|
10 |
|
11 var noOptions = {}; |
|
12 var nonWS = /[^\s\u00a0]/; |
|
13 var Pos = CodeMirror.Pos; |
|
14 |
|
15 function firstNonWS(str) { |
|
16 var found = str.search(nonWS); |
|
17 return found == -1 ? 0 : found; |
|
18 } |
|
19 |
|
20 CodeMirror.commands.toggleComment = function(cm) { |
|
21 var minLine = Infinity, ranges = cm.listSelections(), mode = null; |
|
22 for (var i = ranges.length - 1; i >= 0; i--) { |
|
23 var from = ranges[i].from(), to = ranges[i].to(); |
|
24 if (from.line >= minLine) continue; |
|
25 if (to.line >= minLine) to = Pos(minLine, 0); |
|
26 minLine = from.line; |
|
27 if (mode == null) { |
|
28 if (cm.uncomment(from, to)) mode = "un"; |
|
29 else { cm.lineComment(from, to); mode = "line"; } |
|
30 } else if (mode == "un") { |
|
31 cm.uncomment(from, to); |
|
32 } else { |
|
33 cm.lineComment(from, to); |
|
34 } |
|
35 } |
|
36 }; |
|
37 |
|
38 CodeMirror.defineExtension("lineComment", function(from, to, options) { |
|
39 if (!options) options = noOptions; |
|
40 var self = this, mode = self.getModeAt(from); |
|
41 var commentString = options.lineComment || mode.lineComment; |
|
42 if (!commentString) { |
|
43 if (options.blockCommentStart || mode.blockCommentStart) { |
|
44 options.fullLines = true; |
|
45 self.blockComment(from, to, options); |
|
46 } |
|
47 return; |
|
48 } |
|
49 var firstLine = self.getLine(from.line); |
|
50 if (firstLine == null) return; |
|
51 var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); |
|
52 var pad = options.padding == null ? " " : options.padding; |
|
53 var blankLines = options.commentBlankLines || from.line == to.line; |
|
54 |
|
55 self.operation(function() { |
|
56 if (options.indent) { |
|
57 var baseString = firstLine.slice(0, firstNonWS(firstLine)); |
|
58 for (var i = from.line; i < end; ++i) { |
|
59 var line = self.getLine(i), cut = baseString.length; |
|
60 if (!blankLines && !nonWS.test(line)) continue; |
|
61 if (line.slice(0, cut) != baseString) cut = firstNonWS(line); |
|
62 self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); |
|
63 } |
|
64 } else { |
|
65 for (var i = from.line; i < end; ++i) { |
|
66 if (blankLines || nonWS.test(self.getLine(i))) |
|
67 self.replaceRange(commentString + pad, Pos(i, 0)); |
|
68 } |
|
69 } |
|
70 }); |
|
71 }); |
|
72 |
|
73 CodeMirror.defineExtension("blockComment", function(from, to, options) { |
|
74 if (!options) options = noOptions; |
|
75 var self = this, mode = self.getModeAt(from); |
|
76 var startString = options.blockCommentStart || mode.blockCommentStart; |
|
77 var endString = options.blockCommentEnd || mode.blockCommentEnd; |
|
78 if (!startString || !endString) { |
|
79 if ((options.lineComment || mode.lineComment) && options.fullLines != false) |
|
80 self.lineComment(from, to, options); |
|
81 return; |
|
82 } |
|
83 |
|
84 var end = Math.min(to.line, self.lastLine()); |
|
85 if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; |
|
86 |
|
87 var pad = options.padding == null ? " " : options.padding; |
|
88 if (from.line > end) return; |
|
89 |
|
90 self.operation(function() { |
|
91 if (options.fullLines != false) { |
|
92 var lastLineHasText = nonWS.test(self.getLine(end)); |
|
93 self.replaceRange(pad + endString, Pos(end)); |
|
94 self.replaceRange(startString + pad, Pos(from.line, 0)); |
|
95 var lead = options.blockCommentLead || mode.blockCommentLead; |
|
96 if (lead != null) for (var i = from.line + 1; i <= end; ++i) |
|
97 if (i != end || lastLineHasText) |
|
98 self.replaceRange(lead + pad, Pos(i, 0)); |
|
99 } else { |
|
100 self.replaceRange(endString, to); |
|
101 self.replaceRange(startString, from); |
|
102 } |
|
103 }); |
|
104 }); |
|
105 |
|
106 CodeMirror.defineExtension("uncomment", function(from, to, options) { |
|
107 if (!options) options = noOptions; |
|
108 var self = this, mode = self.getModeAt(from); |
|
109 var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end); |
|
110 |
|
111 // Try finding line comments |
|
112 var lineString = options.lineComment || mode.lineComment, lines = []; |
|
113 var pad = options.padding == null ? " " : options.padding, didSomething; |
|
114 lineComment: { |
|
115 if (!lineString) break lineComment; |
|
116 for (var i = start; i <= end; ++i) { |
|
117 var line = self.getLine(i); |
|
118 var found = line.indexOf(lineString); |
|
119 if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; |
|
120 if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; |
|
121 if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; |
|
122 lines.push(line); |
|
123 } |
|
124 self.operation(function() { |
|
125 for (var i = start; i <= end; ++i) { |
|
126 var line = lines[i - start]; |
|
127 var pos = line.indexOf(lineString), endPos = pos + lineString.length; |
|
128 if (pos < 0) continue; |
|
129 if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; |
|
130 didSomething = true; |
|
131 self.replaceRange("", Pos(i, pos), Pos(i, endPos)); |
|
132 } |
|
133 }); |
|
134 if (didSomething) return true; |
|
135 } |
|
136 |
|
137 // Try block comments |
|
138 var startString = options.blockCommentStart || mode.blockCommentStart; |
|
139 var endString = options.blockCommentEnd || mode.blockCommentEnd; |
|
140 if (!startString || !endString) return false; |
|
141 var lead = options.blockCommentLead || mode.blockCommentLead; |
|
142 var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); |
|
143 var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); |
|
144 if (close == -1 && start != end) { |
|
145 endLine = self.getLine(--end); |
|
146 close = endLine.lastIndexOf(endString); |
|
147 } |
|
148 if (open == -1 || close == -1 || |
|
149 !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || |
|
150 !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) |
|
151 return false; |
|
152 |
|
153 self.operation(function() { |
|
154 self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), |
|
155 Pos(end, close + endString.length)); |
|
156 var openEnd = open + startString.length; |
|
157 if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; |
|
158 self.replaceRange("", Pos(start, open), Pos(start, openEnd)); |
|
159 if (lead) for (var i = start + 1; i <= end; ++i) { |
|
160 var line = self.getLine(i), found = line.indexOf(lead); |
|
161 if (found == -1 || nonWS.test(line.slice(0, found))) continue; |
|
162 var foundEnd = found + lead.length; |
|
163 if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; |
|
164 self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); |
|
165 } |
|
166 }); |
|
167 return true; |
|
168 }); |
|
169 }); |