From 0c56fc754aa2d3e967dc15e6e8e4226bbb1b6e35 Mon Sep 17 00:00:00 2001
From: Andre von Houck <starplant@gmail.com>
Date: Thu, 5 Jan 2012 23:00:59 -0800
Subject: [PATCH] Fixed coffee script highlighter

$ is a valid identifire
/path no longer breaks
0...1 no does not highlight as 0. .. 1
removed some spaces on blank lines
---
 mode/coffeescript/coffeescript.js | 80 +++++++++++++++++++------------
 1 file changed, 50 insertions(+), 30 deletions(-)

diff --git a/mode/coffeescript/coffeescript.js b/mode/coffeescript/coffeescript.js
index d4d572398..185aadb60 100644
--- a/mode/coffeescript/coffeescript.js
+++ b/mode/coffeescript/coffeescript.js
@@ -4,17 +4,17 @@
  */
 CodeMirror.defineMode('coffeescript', function(conf) {
     var ERRORCLASS = 'error';
-    
+
     function wordRegexp(words) {
         return new RegExp("^((" + words.join(")|(") + "))\\b");
     }
-    
+
     var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
     var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
     var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
     var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
     var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
-    var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+    var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
 
     var wordOperators = wordRegexp(['and', 'or', 'not',
                                     'is', 'isnt', 'in',
@@ -57,15 +57,21 @@ CodeMirror.defineMode('coffeescript', function(conf) {
         if (stream.eatSpace()) {
             return null;
         }
-        
+
         var ch = stream.peek();
-        
-        // Handle comments
+
+        // Handle multi line comments
+        if (stream.match("###")) {
+            state.tokenize = longComment;
+            return state.tokenize(stream, state);
+        }
+
+        // Single line comment
         if (ch === '#') {
             stream.skipToEnd();
             return 'comment';
         }
-        
+
         // Handle number literals
         if (stream.match(/^-?[0-9\.]/, false)) {
             var floatLiteral = false;
@@ -79,7 +85,12 @@ CodeMirror.defineMode('coffeescript', function(conf) {
             if (stream.match(/^-?\.\d+/)) {
               floatLiteral = true;
             }
+
             if (floatLiteral) {
+                // prevent from getting extra . on 1..
+                if (stream.peek() == "."){
+                    stream.backUp(1);
+                }
                 return 'number';
             }
             // Integers
@@ -100,7 +111,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
                 return 'number';
             }
         }
-        
+
         // Handle strings
         if (stream.match(stringPrefixes)) {
             state.tokenize = tokenFactory(stream.current(), 'string');
@@ -115,7 +126,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
                 stream.backUp(1);
             }
         }
-        
+
         // Handle operators and delimiters
         if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
             return 'punctuation';
@@ -128,28 +139,26 @@ CodeMirror.defineMode('coffeescript', function(conf) {
         if (stream.match(singleDelimiters)) {
             return 'punctuation';
         }
-        
+
         if (stream.match(constants)) {
             return 'atom';
         }
-        
+
         if (stream.match(keywords)) {
             return 'keyword';
         }
-        
+
         if (stream.match(identifiers)) {
             return 'variable';
         }
-        
+
         // Handle non-detected items
         stream.next();
         return ERRORCLASS;
     }
-    
+
     function tokenFactory(delimiter, outclass) {
-        var delim_re = new RegExp(delimiter);
         var singleline = delimiter.length == 1;
-        
         return function tokenString(stream, state) {
             while (!stream.eol()) {
                 stream.eatWhile(/[^'"\/\\]/);
@@ -158,7 +167,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
                     if (singleline && stream.eol()) {
                         return outclass;
                     }
-                } else if (stream.match(delim_re)) {
+                } else if (stream.match(delimiter)) {
                     state.tokenize = tokenBase;
                     return outclass;
                 } else {
@@ -175,7 +184,18 @@ CodeMirror.defineMode('coffeescript', function(conf) {
             return outclass;
         };
     }
-    
+
+    function longComment(stream, state) {
+        while (!stream.eol()) {
+            stream.eatWhile(/[^#]/);
+            if (stream.match("###")) {
+                state.tokenize = tokenBase;
+                break;
+            }
+        }
+        return "comment"
+    }
+
     function indent(stream, state, type) {
         type = type || 'coffee';
         var indentUnit = 0;
@@ -194,7 +214,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
             type: type
         });
     }
-    
+
     function dedent(stream, state) {
         if (state.scopes.length == 1) return;
         if (state.scopes[0].type === 'coffee') {
@@ -233,7 +253,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
                 return ERRORCLASS;
             }
         }
-        
+
         // Handle properties
         if (current === '@') {
             style = state.tokenize(stream, state);
@@ -244,7 +264,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
                 return ERRORCLASS;
             }
         }
-        
+
         // Handle scope changes.
         if (current === 'return') {
             state.dedent += 1;
@@ -266,7 +286,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
         if (current == 'then'){
             dedent(stream, state);
         }
-        
+
 
         if (style === 'dedent') {
             if (dedent(stream, state)) {
@@ -283,7 +303,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
             if (state.scopes.length > 1) state.scopes.shift();
             state.dedent -= 1;
         }
-        
+
         return style;
     }
 
@@ -297,27 +317,27 @@ CodeMirror.defineMode('coffeescript', function(conf) {
               dedent: 0
           };
         },
-        
+
         token: function(stream, state) {
             var style = tokenLexer(stream, state);
-            
+
             state.lastToken = {style:style, content: stream.current()};
-            
+
             if (stream.eol() && stream.lambda) {
                 state.lambda = false;
             }
-            
+
             return style;
         },
-        
+
         indent: function(state, textAfter) {
             if (state.tokenize != tokenBase) {
                 return 0;
             }
-            
+
             return state.scopes[0].offset;
         }
-        
+
     };
     return external;
 });
-- 
GitLab