diff --git a/doc/compress.html b/doc/compress.html
index eb8b007d47473d122a1f8008bdefd570856b6ae8..b81bd48dda48014d68171e618c50ced666fc13e9 100644
--- a/doc/compress.html
+++ b/doc/compress.html
@@ -167,8 +167,9 @@
           <option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
           <option value="http://codemirror.net/mode/solr/solr.js">solr.js</option>
           <option value="http://codemirror.net/mode/soy/soy.js">soy.js</option>
-          <option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
           <option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
+          <option value="http://codemirror.net/mode/spreadsheet/spreadsheet.js">spreadsheet.js</option>
+          <option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
           <option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
           <option value="http://codemirror.net/mode/tcl/tcl.js">tcl.js</option>
           <option value="http://codemirror.net/mode/textile/textile.js">textile.js</option>
diff --git a/mode/meta.js b/mode/meta.js
index 507b0cc55b5b438038ed9945bfa193d5d43d3d92..fcaed98e2df3f104c60f8e2a267e000059107c22 100644
--- a/mode/meta.js
+++ b/mode/meta.js
@@ -107,6 +107,7 @@
     {name: "Solr", mime: "text/x-solr", mode: "solr"},
     {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
     {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
+    {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
     {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
     {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
     {name: "sTeX", mime: "text/x-stex", mode: "stex"},
diff --git a/mode/spreadsheet/spreadsheet.js b/mode/spreadsheet/spreadsheet.js
index 7f7f495f8c8b174adf763006a9c14386c2ae2830..6fab00fddaf23fcf69a1ce0b735996be0f37a774 100644
--- a/mode/spreadsheet/spreadsheet.js
+++ b/mode/spreadsheet/spreadsheet.js
@@ -12,11 +12,6 @@
   "use strict";
 
   CodeMirror.defineMode("spreadsheet", function () {
-    var stateType = {
-	  string: 'string',
-	  characterClass: 'characterClass'
-    };
-
     return {
       startState: function () {
         return {
@@ -33,78 +28,71 @@
           if ((stream.peek() == '"') || (stream.peek() == "'")) {
             state.stringType = stream.peek();
             stream.next(); // Skip quote
-            state.stack.unshift(stateType.string);
+            state.stack.unshift("string");
           }
         }
 
         //return state
         //stack has
         switch (state.stack[0]) {
-          case stateType.string:
-            while (state.stack[0] === stateType.string && !stream.eol()) {
-              if (stream.peek() === state.stringType) {
-                stream.next(); // Skip quote
-                state.stack.shift(); // Clear flag
-              } else if (stream.peek() === "\\") {
-                stream.next();
-                stream.next();
-              } else {
-                stream.match(/^.[^\\\"\']*/);
-              }
+        case "string":
+          while (state.stack[0] === "string" && !stream.eol()) {
+            if (stream.peek() === state.stringType) {
+              stream.next(); // Skip quote
+              state.stack.shift(); // Clear flag
+            } else if (stream.peek() === "\\") {
+              stream.next();
+              stream.next();
+            } else {
+              stream.match(/^.[^\\\"\']*/);
             }
-            return "string";
+          }
+          return "string";
 
-          case stateType.characterClass:
-            while (state.stack[0] === stateType.characterClass && !stream.eol()) {
-              if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
-                state.stack.shift();
-              }
-            }
-            return "operator";
+        case "characterClass":
+          while (state.stack[0] === "characterClass" && !stream.eol()) {
+            if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./)))
+              state.stack.shift();
+          }
+          return "operator";
         }
 
         var peek = stream.peek();
 
         //no stack
         switch (peek) {
-          case "[":
-            stream.next();
-            state.stack.unshift(stateType.characterClass);
-            return "bracket";
-          case ":":
-            stream.next();
-            return "operator";
-          case "\\":
-            if (stream.match(/[\][a-z]+/)) {
-              return "string-2";
-            }
-
-          case ".":
-          case ",":
-          case ";":
-          case "*":
-          case "-":
-          case "+":
-          case "^":
-          case "<":
-          case "/":
-          case "=":
-            stream.next();
-            return "atom";
-          case "$":
-            stream.next();
-            return "builtin";
+        case "[":
+          stream.next();
+          state.stack.unshift("characterClass");
+          return "bracket";
+        case ":":
+          stream.next();
+          return "operator";
+        case "\\":
+          if (stream.match(/\\[a-z]+/)) return "string-2";
+          else return null;
+        case ".":
+        case ",":
+        case ";":
+        case "*":
+        case "-":
+        case "+":
+        case "^":
+        case "<":
+        case "/":
+        case "=":
+          stream.next();
+          return "atom";
+        case "$":
+          stream.next();
+          return "builtin";
         }
 
-        if (stream.match(/[0-9]+/)) {
-          if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
-            return "error";
-          }
+        if (stream.match(/\d+/)) {
+          if (stream.match(/^\w+/)) return "error";
           return "number";
-        } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
-          if (stream.match(/(?=[\(.])/, false)) {
-            return "keyword";
-          }
+        } else if (stream.match(/^[a-zA-Z_]\w*/)) {
+          if (stream.match(/(?=[\(.])/, false)) return "keyword";
           return "variable-2";
         } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) {
           stream.next();
@@ -118,4 +106,4 @@
   });
 
   CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet");
-});
\ No newline at end of file
+});