diff --git a/doc/compress.html b/doc/compress.html
index 567c68f453d6228de0f82c06c363f164e67fd687..a9c1bce81bf6ef42ed951d4c6c783737a37c40b3 100644
--- a/doc/compress.html
+++ b/doc/compress.html
@@ -89,6 +89,7 @@
           <option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
           <option value="http://codemirror.net/mode/dtd/dtd.js">dtd.js</option>
           <option value="http://codemirror.net/mode/ecl/ecl.js">ecl.js</option>
+          <option value="http://codemirror.net/mode/eiffel/eiffel.js">eiffel.js</option>
           <option value="http://codemirror.net/mode/erlang/erlang.js">erlang.js</option>
           <option value="http://codemirror.net/mode/fortran/fortran.js">fortran.js</option>
           <option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option>
diff --git a/mode/eiffel/eiffel.js b/mode/eiffel/eiffel.js
new file mode 100644
index 0000000000000000000000000000000000000000..15f34a932508c17efe66e12eb64b411aff043e72
--- /dev/null
+++ b/mode/eiffel/eiffel.js
@@ -0,0 +1,147 @@
+CodeMirror.defineMode("eiffel", function() {
+  function wordObj(words) {
+    var o = {};
+    for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
+    return o;
+  }
+  var keywords = wordObj([
+    'note',
+    'across',
+    'when',
+    'variant',
+    'until',
+    'unique',
+    'undefine',
+    'then',
+    'strip',
+    'select',
+    'retry',
+    'rescue',
+    'require',
+    'rename',
+    'reference',
+    'redefine',
+    'prefix',
+    'once',
+    'old',
+    'obsolete',
+    'loop',
+    'local',
+    'like',
+    'is',
+    'inspect',
+    'infix',
+    'include',
+    'if',
+    'frozen',
+    'from',
+    'external',
+    'export',
+    'ensure',
+    'end',
+    'elseif',
+    'else',
+    'do',
+    'creation',
+    'create',
+    'check',
+    'alias',
+    'agent',
+    'separate',
+    'invariant',
+    'inherit',
+    'indexing',
+    'feature',
+    'expanded',
+    'deferred',
+    'class',
+    'Void',
+    'True',
+    'Result',
+    'Precursor',
+    'False',
+    'Current',
+    'create',
+    'attached',
+    'detachable',
+    'as',
+    'and',
+    'implies',
+    'not',
+    'or'
+  ]);
+  var operators = wordObj([":=", "and then","and", "or","<<",">>"]);
+  var curPunc;
+
+  function chain(newtok, stream, state) {
+    state.tokenize.push(newtok);
+    return newtok(stream, state);
+  }
+
+  function tokenBase(stream, state) {
+    curPunc = null;
+    if (stream.eatSpace()) return null;
+    var ch = stream.next();
+    if (ch == '"'||ch == "'") {
+      return chain(readQuoted(ch, "string"), stream, state);
+    } else if (ch == "-"&&stream.eat("-")) {
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == ":"&&stream.eat("=")) {
+      return "operator";
+    } else if (/[0-9]/.test(ch)) {
+      stream.eatWhile(/[xXbBCc0-9\.]/);
+      stream.eat(/[\?\!]/);
+      return "ident";
+    } else if (/[a-zA-Z_0-9]/.test(ch)) {
+      stream.eatWhile(/[a-zA-Z_0-9]/);
+      stream.eat(/[\?\!]/);
+      return "ident";
+    } else if (/[=+\-\/*^%<>~]/.test(ch)) {
+      stream.eatWhile(/[=+\-\/*^%<>~]/);
+      return "operator";
+    } else {
+      return null;
+    }
+  }
+
+  function readQuoted(quote, style,  unescaped) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && (unescaped || !escaped)) {
+          state.tokenize.pop();
+          break;
+        }
+        escaped = !escaped && ch == "%";
+      }
+      return style;
+    };
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: [tokenBase]};
+    },
+
+    token: function(stream, state) {
+      var style = state.tokenize[state.tokenize.length-1](stream, state);
+      if (style == "ident") {
+        var word = stream.current();
+        style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
+          : operators.propertyIsEnumerable(stream.current()) ? "operator"
+          : /^[A-Z][A-Z_0-9]*$/g.test(word) ? "tag"
+          : /^0[bB][0-1]+$/g.test(word) ? "number"
+          : /^0[cC][0-7]+$/g.test(word) ? "number"
+          : /^0[xX][a-fA-F0-9]+$/g.test(word) ? "number"
+          : /^([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)$/g.test(word) ? "number"
+          : /^[0-9]+$/g.test(word) ? "number"
+          : "variable";
+      }
+      return style;
+    },
+    lineComment: "--"
+  };
+});
+
+CodeMirror.defineMIME("text/x-eiffel", "eiffel");
diff --git a/mode/eiffel/index.html b/mode/eiffel/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..5d395a05cd36df9c5faaa450f4c21007d022b71a
--- /dev/null
+++ b/mode/eiffel/index.html
@@ -0,0 +1,430 @@
+<!doctype html>
+
+<title>CodeMirror: Eiffel mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<link rel="stylesheet" href="../../theme/neat.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="eiffel.js"></script>
+<style>
+      .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
+      .cm-s-default span.cm-arrow { color: red; }
+    </style>
+<div id=nav>
+  <a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/marijnh/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">Eiffel</a>
+  </ul>
+</div>
+
+<article>
+<h2>Eiffel mode</h2>
+<form><textarea id="code" name="code">
+note
+    description: "[
+        Project-wide universal properties.
+        This class is an ancestor to all developer-written classes.
+        ANY may be customized for individual projects or teams.
+        ]"
+
+    library: "Free implementation of ELKS library"
+    status: "See notice at end of class."
+    legal: "See notice at end of class."
+    date: "$Date: 2013-01-25 11:49:00 -0800 (Fri, 25 Jan 2013) $"
+    revision: "$Revision: 712 $"
+
+class
+    ANY
+
+feature -- Customization
+
+feature -- Access
+
+    generator: STRING
+            -- Name of current object's generating class
+            -- (base class of the type of which it is a direct instance)
+        external
+            "built_in"
+        ensure
+            generator_not_void: Result /= Void
+            generator_not_empty: not Result.is_empty
+        end
+
+    generating_type: TYPE [detachable like Current]
+            -- Type of current object
+            -- (type of which it is a direct instance)
+        do
+            Result := {detachable like Current}
+        ensure
+            generating_type_not_void: Result /= Void
+        end
+
+feature -- Status report
+
+    conforms_to (other: ANY): BOOLEAN
+            -- Does type of current object conform to type
+            -- of `other' (as per Eiffel: The Language, chapter 13)?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        end
+
+    same_type (other: ANY): BOOLEAN
+            -- Is type of current object identical to type of `other'?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            definition: Result = (conforms_to (other) and
+                                        other.conforms_to (Current))
+        end
+
+feature -- Comparison
+
+    is_equal (other: like Current): BOOLEAN
+            -- Is `other' attached to an object considered
+            -- equal to current object?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            symmetric: Result implies other ~ Current
+            consistent: standard_is_equal (other) implies Result
+        end
+
+    frozen standard_is_equal (other: like Current): BOOLEAN
+            -- Is `other' attached to an object of the same type
+            -- as current object, and field-by-field identical to it?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            same_type: Result implies same_type (other)
+            symmetric: Result implies other.standard_is_equal (Current)
+        end
+
+    frozen equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void or attached
+            -- to objects considered equal?
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then
+                            a.is_equal (b)
+            end
+        ensure
+            definition: Result = (a = Void and b = Void) or else
+                        ((a /= Void and b /= Void) and then
+                        a.is_equal (b))
+        end
+
+    frozen standard_equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void or attached to
+            -- field-by-field identical objects of the same type?
+            -- Always uses default object comparison criterion.
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then
+                            a.standard_is_equal (b)
+            end
+        ensure
+            definition: Result = (a = Void and b = Void) or else
+                        ((a /= Void and b /= Void) and then
+                        a.standard_is_equal (b))
+        end
+
+    frozen is_deep_equal (other: like Current): BOOLEAN
+            -- Are `Current' and `other' attached to isomorphic object structures?
+        require
+            other_not_void: other /= Void
+        external
+            "built_in"
+        ensure
+            shallow_implies_deep: standard_is_equal (other) implies Result
+            same_type: Result implies same_type (other)
+            symmetric: Result implies other.is_deep_equal (Current)
+        end
+
+    frozen deep_equal (a: detachable ANY; b: like a): BOOLEAN
+            -- Are `a' and `b' either both void
+            -- or attached to isomorphic object structures?
+        do
+            if a = Void then
+                Result := b = Void
+            else
+                Result := b /= Void and then a.is_deep_equal (b)
+            end
+        ensure
+            shallow_implies_deep: standard_equal (a, b) implies Result
+            both_or_none_void: (a = Void) implies (Result = (b = Void))
+            same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b))
+            symmetric: Result implies deep_equal (b, a)
+        end
+
+feature -- Duplication
+
+    frozen twin: like Current
+            -- New object equal to `Current'
+            -- `twin' calls `copy'; to change copying/twinning semantics, redefine `copy'.
+        external
+            "built_in"
+        ensure
+            twin_not_void: Result /= Void
+            is_equal: Result ~ Current
+        end
+
+    copy (other: like Current)
+            -- Update current object using fields of object attached
+            -- to `other', so as to yield equal objects.
+        require
+            other_not_void: other /= Void
+            type_identity: same_type (other)
+        external
+            "built_in"
+        ensure
+            is_equal: Current ~ other
+        end
+
+    frozen standard_copy (other: like Current)
+            -- Copy every field of `other' onto corresponding field
+            -- of current object.
+        require
+            other_not_void: other /= Void
+            type_identity: same_type (other)
+        external
+            "built_in"
+        ensure
+            is_standard_equal: standard_is_equal (other)
+        end
+
+    frozen clone (other: detachable ANY): like other
+            -- Void if `other' is void; otherwise new object
+            -- equal to `other'
+            --
+            -- For non-void `other', `clone' calls `copy';
+            -- to change copying/cloning semantics, redefine `copy'.
+        obsolete
+            "Use `twin' instead."
+        do
+            if other /= Void then
+                Result := other.twin
+            end
+        ensure
+            equal: Result ~ other
+        end
+
+    frozen standard_clone (other: detachable ANY): like other
+            -- Void if `other' is void; otherwise new object
+            -- field-by-field identical to `other'.
+            -- Always uses default copying semantics.
+        obsolete
+            "Use `standard_twin' instead."
+        do
+            if other /= Void then
+                Result := other.standard_twin
+            end
+        ensure
+            equal: standard_equal (Result, other)
+        end
+
+    frozen standard_twin: like Current
+            -- New object field-by-field identical to `other'.
+            -- Always uses default copying semantics.
+        external
+            "built_in"
+        ensure
+            standard_twin_not_void: Result /= Void
+            equal: standard_equal (Result, Current)
+        end
+
+    frozen deep_twin: like Current
+            -- New object structure recursively duplicated from Current.
+        external
+            "built_in"
+        ensure
+            deep_twin_not_void: Result /= Void
+            deep_equal: deep_equal (Current, Result)
+        end
+
+    frozen deep_clone (other: detachable ANY): like other
+            -- Void if `other' is void: otherwise, new object structure
+            -- recursively duplicated from the one attached to `other'
+        obsolete
+            "Use `deep_twin' instead."
+        do
+            if other /= Void then
+                Result := other.deep_twin
+            end
+        ensure
+            deep_equal: deep_equal (other, Result)
+        end
+
+    frozen deep_copy (other: like Current)
+            -- Effect equivalent to that of:
+            --      `copy' (`other' . `deep_twin')
+        require
+            other_not_void: other /= Void
+        do
+            copy (other.deep_twin)
+        ensure
+            deep_equal: deep_equal (Current, other)
+        end
+
+feature {NONE} -- Retrieval
+
+    frozen internal_correct_mismatch
+            -- Called from runtime to perform a proper dynamic dispatch on `correct_mismatch'
+            -- from MISMATCH_CORRECTOR.
+        local
+            l_msg: STRING
+            l_exc: EXCEPTIONS
+        do
+            if attached {MISMATCH_CORRECTOR} Current as l_corrector then
+                l_corrector.correct_mismatch
+            else
+                create l_msg.make_from_string ("Mismatch: ")
+                create l_exc
+                l_msg.append (generating_type.name)
+                l_exc.raise_retrieval_exception (l_msg)
+            end
+        end
+
+feature -- Output
+
+    io: STD_FILES
+            -- Handle to standard file setup
+        once
+            create Result
+            Result.set_output_default
+        ensure
+            io_not_void: Result /= Void
+        end
+
+    out: STRING
+            -- New string containing terse printable representation
+            -- of current object
+        do
+            Result := tagged_out
+        ensure
+            out_not_void: Result /= Void
+        end
+
+    frozen tagged_out: STRING
+            -- New string containing terse printable representation
+            -- of current object
+        external
+            "built_in"
+        ensure
+            tagged_out_not_void: Result /= Void
+        end
+
+    print (o: detachable ANY)
+            -- Write terse external representation of `o'
+            -- on standard output.
+        do
+            if o /= Void then
+                io.put_string (o.out)
+            end
+        end
+
+feature -- Platform
+
+    Operating_environment: OPERATING_ENVIRONMENT
+            -- Objects available from the operating system
+        once
+            create Result
+        ensure
+            operating_environment_not_void: Result /= Void
+        end
+
+feature {NONE} -- Initialization
+
+    default_create
+            -- Process instances of classes with no creation clause.
+            -- (Default: do nothing.)
+        do
+        end
+
+feature -- Basic operations
+
+    default_rescue
+            -- Process exception for routines with no Rescue clause.
+            -- (Default: do nothing.)
+        do
+        end
+
+    frozen do_nothing
+            -- Execute a null action.
+        do
+        end
+
+    frozen default: detachable like Current
+            -- Default value of object's type
+        do
+        end
+
+    frozen default_pointer: POINTER
+            -- Default value of type `POINTER'
+            -- (Avoid the need to write `p'.`default' for
+            -- some `p' of type `POINTER'.)
+        do
+        ensure
+            -- Result = Result.default
+        end
+
+    frozen as_attached: attached like Current
+            -- Attached version of Current
+            -- (Can be used during transitional period to convert
+            -- non-void-safe classes to void-safe ones.)
+        do
+            Result := Current
+        end
+
+invariant
+    reflexive_equality: standard_is_equal (Current)
+    reflexive_conformance: conforms_to (Current)
+
+note
+    copyright: "Copyright (c) 1984-2012, Eiffel Software and others"
+    license:   "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
+    source: "[
+            Eiffel Software
+            5949 Hollister Ave., Goleta, CA 93117 USA
+            Telephone 805-685-1006, Fax 805-685-6869
+            Website http://www.eiffel.com
+            Customer support http://support.eiffel.com
+        ]"
+
+end
+
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+        mode: "text/x-eiffel",
+        tabMode: "indent",
+        indentUnit: 4,
+        lineNumbers: true,
+        theme: "neat"
+      });
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>text/x-eiffel</code>.</p>
+ 
+ <p> Created by <a href="https://github.com/ynh">YNH</a>.</p>
+  </article>
diff --git a/mode/index.html b/mode/index.html
index f72b1f062293d4d53289458d6ff0580b11d10579..cbdef24f09b10b7fd4642c30b9c63415b2215d38 100644
--- a/mode/index.html
+++ b/mode/index.html
@@ -43,6 +43,7 @@ option.</p>
       <li><a href="diff/index.html">diff</a></li>
       <li><a href="dtd/index.html">DTD</a></li>
       <li><a href="ecl/index.html">ECL</a></li>
+      <li><a href="eiffel/index.html">Eiffel</a></li>
       <li><a href="erlang/index.html">Erlang</a></li>
       <li><a href="fortran/index.html">Fortran</a></li>
       <li><a href="gas/index.html">Gas</a> (AT&amp;T-style assembly)</li>
diff --git a/mode/meta.js b/mode/meta.js
index fe5cd848a67f1734cdc10ba94d08b998817b9e8b..f6bbd1b45cab50821dce4c598f1b9e6d26e303aa 100644
--- a/mode/meta.js
+++ b/mode/meta.js
@@ -15,6 +15,7 @@ CodeMirror.modeInfo = [
   {name: 'diff', mime: 'text/x-diff', mode: 'diff'},
   {name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'},
   {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
+  {name: 'Eiffel', mime: 'text/x-eiffel', mode: 'eiffel'},
   {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
   {name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'},
   {name: 'Gas', mime: 'text/x-gas', mode: 'gas'},