var session = require("zed/session");

function Stripper(info, callback) {
    this.path = info.path;
    this.min = info.inserts.preferences.trimEmptyLines ? -1 : 0;
    this.lines = info.inserts.lines;
    this.currentLine = info.inserts.cursor.row;

    // Don't strip mid-snippet.
    if (!info.inserts.isInsertingSnippet) {
        this.stripTrailing();
    }
    callback();
}

Stripper.prototype = {
    stripTrailing: function() {
        // Strip spaces from the ends of lines.
        for (var i = 0; i < this.lines.length; i++) {
            // Preserve spaces on the line we're on.
            if (i == this.currentLine) {
                continue;
            }

            // Don't do the strip if the line contains only spaces
            // and the preference to trimEmptyLines isn't set.
            var column = this.lines[i].search(/\s+$/);
            if (column > this.min) {
                session.removeInLine(this.path, i, column, this.lines[i].length);
            }
        }

        this.checkEOF();
    },

    checkEOF: function() {
        var lastTwo = this.lines.slice(-2);
        if (lastTwo[1] !== "") {
            // Enforce newline at end of file.
            session.append(this.path, "\n", this.final);
        } else if (lastTwo[0] === "" && lastTwo[1] === "") {
            // Strip blank lines from the end.
            this.stripEndLines();
        }
    },

    stripEndLines: function() {
        var len = this.lines.length;
        // Don't strip beyond the cursor position.
        for (var i = len; i > this.currentLine; i--) {
            if (this.lines[i - 1] !== "") {
                break;
            }
        }
        if (i < len - 1) {
            session.removeLines(this.path, i, len);
        }
    },
};

module.exports = function(info, callback) {
    // Don't auto-strip if the preference isn't set, but do allow manual use.
    if (!(!info.inserts.preferences.trimWhitespaceOnSave && info.internal)) {
        new Stripper(info, callback);
    }
};

@@ -36,460 +36,424 @@
 );%0A%0A
-function Stripper(info, callback) %7B%0A    this.path = info.path;%0A    this.min = info.inserts.preferences.trimEmptyLines ? -1 : 0;%0A    this.lines = info.inserts.lines;%0A    this.currentLine = info.inserts.cursor.row;%0A%0A    // Don't strip mid-snippet.%0A    if (!info.inserts.isInsertingSnippet) %7B%0A        this.stripTrailing();%0A    %7D%0A    callback();%0A%7D%0A%0AStripper.prototype = %7B%0A    stripTrailing: function() %7B%0A        // Strip spaces from the ends of lines.%0A    
+module.exports = function(info, callback) %7B%0A    // Don't strip while inserting snippets, or auto-strip when pref not set.%0A    if (info.inserts.isInsertingSnippet %7C%7C (!info.inserts.preferences.trimWhitespaceOnSave && info.internal)) %7B%0A        return callback();%0A    %7D%0A%0A    var min = info.inserts.preferences.trimEmptyLines ? -1 : 0;%0A    var currentLine = info.inserts.cursor.row;%0A    var lines = info.inserts.lines;%0A%0A
     
@@ -472,21 +472,16 @@
  0; i %3C 
-this.
 lines.le
@@ -489,28 +489,24 @@
 gth; i++) %7B%0A
-    
         // P
@@ -546,28 +546,24 @@
 on.%0A        
-    
 if (i == thi
@@ -559,21 +559,16 @@
 f (i == 
-this.
 currentL
@@ -576,185 +576,19 @@
 ne) 
-%7B%0A                continue;%0A            %7D%0A%0A            // Don't do the strip if the line contains only spaces%0A            // and the preference to trimEmptyLines isn't set.%0A    
+continue;%0A%0A
     
@@ -600,29 +600,24 @@
 ar column = 
-this.
 lines%5Bi%5D.sea
@@ -633,28 +633,24 @@
 /);%0A        
-  
-  
 if (column %3E
@@ -654,24 +654,15 @@
 n %3E 
-this.
 min) %7B%0A
-    
     
@@ -690,20 +690,20 @@
 eInLine(
-this
+info
 .path, i
@@ -712,21 +712,16 @@
 column, 
-this.
 lines%5Bi%5D
@@ -742,149 +742,46 @@
     
-    %7D%0A  
+%7D%0A
     
-  
 %7D%0A%0A    
-   
- this.checkEOF();%0A    %7D,%0A%0A    checkEOF: function() %7B%0A        var lastTwo = this.lines.slice(-2);%0A        if (lastTwo%5B
+if (lines%5Blines.length - 
 1%5D !
@@ -781,36 +781,32 @@
  - 1%5D !== %22%22) %7B%0A
-    
         // Enfor
@@ -832,35 +832,38 @@
 f file.%0A        
-   
+return
  session.append(
@@ -862,20 +862,20 @@
 .append(
-this
+info
 .path, %22
@@ -883,212 +883,96 @@
 n%22, 
-this.final);%0A        %7D else if (lastTwo%5B0%5D === %22%22 && lastTwo%5B1%5D === %22%22) %7B%0A            // Strip blank lines from the end.%0A            this.stripEndLines();%0A        %7D%0A    %7D,%0A%0A    stripEndLines: function() %7B
+callback);%0A    %7D else %7B%0A        // Strip blank lines, but not above the cursor position.
 %0A   
@@ -984,19 +984,14 @@
 var 
-len = this.
+row = 
 line
@@ -1012,216 +1012,104 @@
     
-// Don't strip beyond the cursor position.%0A        for (var i = len; i %3E this.currentLine; i--) %7B%0A            if (this.
+while ((row %3E currentLine) && (
 lines%5B
-i
+row
  - 1%5D 
-!
+=
 == %22%22)
+)
  %7B
-%0A                break;%0A            %7D%0A        %7D%0A        if (i %3C len
+ row--; %7D%0A        if (row %3C lines.length
  - 1
@@ -1116,32 +1116,39 @@
 ) %7B%0A            
+return 
 session.removeLi
@@ -1155,79 +1155,36 @@
 nes(
-this
+info
 .path, 
-i, len);%0A        %7D%0A    %7D,%0A%7D;%0A%0Amodule.exports = function(info
+row, lines.length
 , ca
@@ -1194,193 +1194,29 @@
 ack)
- %7B
+;
 %0A    
-// Don't auto-strip if the preference isn't set, but do allow manual use.%0A    if (!(!info.inserts.preferences.trimWhitespaceOnSave && info.internal)) %7B%0A        new Stripper(info,
+    %7D%0A    %7D%0A   
  cal
@@ -1220,20 +1220,15 @@
 callback
+(
 );%0A
-    %7D%0A
 %7D;%0A

Streamline stripper.js without any callbacks.