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