diff --git a/mode/sass/sass.js b/mode/sass/sass.js
index 3ac48018f02127e3123a91efc109d5a0606c64ad..52a668291591092820cd11931a1011bfcb8ca7d8 100644
--- a/mode/sass/sass.js
+++ b/mode/sass/sass.js
@@ -19,10 +19,11 @@ CodeMirror.defineMode("sass", function(config) {
   var keywords = ["true", "false", "null", "auto"];
   var keywordsRegexp = new RegExp("^" + keywords.join("|"));
 
-  var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
+  var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-",
+                   "\\!=", "/", "\\*", "%", "and", "or", "not", ";","\\{","\\}",":"];
   var opRegexp = tokenRegexp(operators);
 
-  var pseudoElementsRegexp = /^::[\w\-]+/;
+  var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/;
 
   function urlTokens(stream, state) {
     var ch = stream.peek();
@@ -56,7 +57,7 @@ CodeMirror.defineMode("sass", function(config) {
         stream.next();
         state.tokenizer = tokenBase;
       } else {
-        stream.next();
+        stream.skipToEnd();
       }
 
       return "comment";
@@ -135,178 +136,216 @@ CodeMirror.defineMode("sass", function(config) {
       return "operator";
     }
 
-    if (ch === ".") {
+    // Strings
+    if (ch === '"' || ch === "'") {
       stream.next();
-
-      // Match class selectors
-      if (stream.match(/^[\w-]+/)) {
-        indent(state);
-        return "atom";
-      } else if (stream.peek() === "#") {
-        indent(state);
-        return "atom";
-      } else {
-        return "operator";
-      }
+      state.tokenizer = buildStringTokenizer(ch);
+      return "string";
     }
 
-    if (ch === "#") {
-      stream.next();
+    if(!state.cursorHalf){// state.cursorHalf === 0
+    // first half i.e. before : for key-value pairs
+    // including selectors
 
-      // Hex numbers
-      if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/))
-        return "number";
+      if (ch === ".") {
+        stream.next();
+        if (stream.match(/^[\w-]+/)) {
+          indent(state);
+          return "atom";
+        } else if (stream.peek() === "#") {
+          indent(state);
+          return "atom";
+        }
+      }
 
-      // ID selectors
-      if (stream.match(/^[\w-]+/)) {
-        indent(state);
-        return "atom";
+      if (ch === "#") {
+        stream.next();
+        // ID selectors
+        if (stream.match(/^[\w-]+/)) {
+          indent(state);
+          return "atom";
+        }
+        if (stream.peek() === "#") {
+          indent(state);
+          return "atom";
+        }
       }
 
-      if (stream.peek() === "#") {
-        indent(state);
-        return "atom";
+      // Variables
+      if (ch === "$") {
+        stream.next();
+        stream.eatWhile(/[\w-]/);
+        return "variable-2";
       }
-    }
 
-    // Numbers
-    if (stream.match(/^-?[0-9\.]+/))
-      return "number";
+      // Numbers
+      if (stream.match(/^-?[0-9\.]+/))
+        return "number";
+
+      // Units
+      if (stream.match(/^(px|em|in)\b/))
+        return "unit";
 
-    // Units
-    if (stream.match(/^(px|em|in)\b/))
-      return "unit";
+      if (stream.match(keywordsRegexp))
+        return "keyword";
 
-    if (stream.match(keywordsRegexp))
-      return "keyword";
+      if (stream.match(/^url/) && stream.peek() === "(") {
+        state.tokenizer = urlTokens;
+        return "atom";
+      }
 
-    if (stream.match(/^url/) && stream.peek() === "(") {
-      state.tokenizer = urlTokens;
-      return "atom";
-    }
+      if (ch === "=") {
+        // Match shortcut mixin definition
+        if (stream.match(/^=[\w-]+/)) {
+          indent(state);
+          return "meta";
+        }
+      }
 
-    // Variables
-    if (ch === "$") {
-      stream.next();
-      stream.eatWhile(/[\w-]/);
-      stream.eatSpace();
-      if (stream.peek() === ":")
-        return "variable-2";
-      else
-        return "variable-3";
-    }
+      if (ch === "+") {
+        // Match shortcut mixin definition
+        if (stream.match(/^\+[\w-]+/)){
+          return "variable-3";
+        }
+      }
 
-    if (ch === "!") {
-      stream.next();
-      return stream.match(/^[\w]+/) ? "keyword": "operator";
-    }
+      if(ch === "@"){
+        if(stream.match(/@extend/)){
+          if(!stream.match(/\s*[\w]/))
+            dedent(state);
+        }
+      }
 
-    if (ch === "=") {
-      stream.next();
 
-      // Match shortcut mixin definition
-      if (stream.match(/^[\w-]+/)) {
+      // Indent Directives
+      if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
         indent(state);
         return "meta";
-      } else {
-        return "operator";
       }
-    }
 
-    if (ch === "+") {
-      stream.next();
+      // Other Directives
+      if (ch === "@") {
+        stream.next();
+        stream.eatWhile(/[\w-]/);
+        return "meta";
+      }
 
-      // Match shortcut mixin definition
-      if (stream.match(/^[\w-]+/))
-        return "variable-3";
-      else
+      if (stream.eatWhile(/[\w-]/)){
+        if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){
+          return "propery";
+        }
+        else if(stream.match(/ *:/,false)){
+          indent(state);
+          state.cursorHalf = 1;
+          return "atom";
+        }
+        else if(stream.match(/ *,/,false)){
+          return "atom";
+        }
+        else{
+          indent(state);
+          return "atom";
+        }
+      }
+
+      if(ch === ":"){
+        if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element
+          return "keyword";
+        }
+        stream.next();
+        state.cursorHalf=1;
         return "operator";
-    }
+      }
 
-    // Indent Directives
-    if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
-      indent(state);
-      return "meta";
-    }
+    } // cursorHalf===0 ends here
+    else{
 
-    // Other Directives
-    if (ch === "@") {
-      stream.next();
-      stream.eatWhile(/[\w-]/);
-      return "meta";
-    }
+      if (ch === "#") {
+        stream.next();
+        // Hex numbers
+        if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
+          if(!stream.peek()){
+            state.cursorHalf = 0;
+          }
+          return "number";
+        }
+      }
 
-    // Strings
-    if (ch === '"' || ch === "'") {
-      stream.next();
-      state.tokenizer = buildStringTokenizer(ch);
-      return "string";
-    }
+      // Numbers
+      if (stream.match(/^-?[0-9\.]+/)){
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
+        return "number";
+      }
+
+      // Units
+      if (stream.match(/^(px|em|in)\b/)){
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
+        return "unit";
+      }
 
-    // Pseudo element selectors and values after colon
-    if (ch === ":"){
-      if (stream.match(pseudoElementsRegexp))
+      if (stream.match(keywordsRegexp)){
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
         return "keyword";
-      stream.next();
-      stream.eatSpace();
-      if (stream.peek() === null){
-        // if there is no more space after it
-        indent(state);
-        return "atom";
       }
 
-      // all posible tokens after colon
-      if (stream.match(/\$[\w-]+/)){
-        // variables
-        return "variable-3";
-      } else if (stream.match(/^url/) && stream.peek() === "(") {
-        //urls
+      if (stream.match(/^url/) && stream.peek() === "(") {
         state.tokenizer = urlTokens;
-        return "atom";
-      } else if (stream.match(/#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}/)){
-        //hexadecimal value
-        return "number";
-      } else if (stream.match(/^-?[0-9\.]+/)){
-        return "number";
-      } else if (stream.match(keywordsRegexp)){
-        return "keyword";
-      } else if (stream.match(/[\w-,\s]+/)){
-        // other text
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
         return "atom";
       }
-    }
 
-    if (stream.match(opRegexp))
-      return "operator";
+      // Variables
+      if (ch === "$") {
+        stream.next();
+        stream.eatWhile(/[\w-]/);
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
+        return "variable-3";
+      }
 
-    // atoms
-    if (stream.eatWhile(/[\w-&]/)) {
-      stream.eatSpace();
-      // matches a property definition
-      if (stream.peek() === ":" ){
-        if (!stream.match(/:[ ]*[\d\w-\$\+#!\("']/,false)){
-         //for cases where line ends after colon
-         // eg
-         // font:
-         //   | <-----cursor
-          indent(state);
-          return "property";
-        } else if (!stream.match(pseudoElementsRegexp, false)){
-          return "property";
+      // bang character for !important, !default, etc.
+      if (ch === "!") {
+        stream.next();
+        if(!stream.peek()){
+          state.cursorHalf = 0;
         }
-      } else {
-        stream.eatSpace();
-        if (stream.peek() !== "," ){
-          //for cases where line ends after comma
-          //eg
-          //head,
-          //body,
-          //| <-----cursor
-          indent(state);
+        return stream.match(/^[\w]+/) ? "keyword": "operator";
+      }
+
+      if (stream.match(opRegexp)){
+        if(!stream.peek()){
+          state.cursorHalf = 0;
         }
-        return "atom";
+        return "operator";
+      }
+
+      // attributes
+      if (stream.eatWhile(/[\w-]/)) {
+        if(!stream.peek()){
+          state.cursorHalf = 0;
+        }
+        return "attribute";
       }
-    }
+
+      //stream.eatSpace();
+      if(!stream.peek()){
+        state.cursorHalf = 0;
+        return null;
+      }
+
+    } // else ends here
+
+    if (stream.match(opRegexp))
+      return "operator";
 
     // If we haven't returned by now, we move 1 character
     // and return an error
@@ -319,11 +358,13 @@ CodeMirror.defineMode("sass", function(config) {
     var style = state.tokenizer(stream, state);
     var current = stream.current();
 
-    if (current === "@return")
+    if (current === "@return" || current === "}"){
       dedent(state);
+    }
 
     if (style !== null) {
       var startOfToken = stream.pos - current.length;
+
       var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
 
       var newScopes = [];
@@ -348,6 +389,8 @@ CodeMirror.defineMode("sass", function(config) {
         tokenizer: tokenBase,
         scopes: [{offset: 0, type: "sass"}],
         indentCount: 0,
+        cursorHalf: 0,  // cursor half tells us if cursor lies after (1)
+                        // or before (0) colon (well... more or less)
         definedVars: [],
         definedMixins: []
       };