Highlighting FIXME

I’d like to be able to add code to highlight certain words in comments in Clike and Properties files. I’m not sure how to accomplish that. I’m looking at the code in ACE to do it, and I would like help porting it to CodeMirror:
DocCommentHighlightRules.getTagRule = function(start) {
return {
token : “comment.doc.tag.storage.type”,
regex : “\b(?:TODO|FIXME|XXX|HACK)\b”
};
}

CodeMirror modes work very different from ACE, so that snippet won’t help much. The easiest way to accomplish what you are describing is probaby an overlay or, if you want to wrap a specific mode, the overlay mode combinator.

Nice idea, but I decided to code it in clike.js and properties.js:

diff -cbr CodeMirror-master/lib/codemirror.css swimpc/commontest/CodeMirror/lib/codemirror.css
*** CodeMirror-master/lib/codemirror.css    Mon Jan 19 03:24:04 2015
--- swimpc/commontest/CodeMirror/lib/codemirror.css    Thu Mar 12 09:58:04 2015
***************
*** 103,108 ****
--- 103,109 ----
  .cm-s-default .cm-variable-2 {color: #05a;}
  .cm-s-default .cm-variable-3 {color: #085;}
  .cm-s-default .cm-comment {color: #a50;}
+ .cm-s-default .cm-commentHighlight {color: #a50; background-color: yellow; }    /* JMO */
  .cm-s-default .cm-string {color: #a11;}
  .cm-s-default .cm-string-2 {color: #f50;}
  .cm-s-default .cm-meta {color: #555;}
diff -cbr CodeMirror-master/mode/clike/clike.js swimpc/commontest/CodeMirror/mode/clike/clike.js
*** CodeMirror-master/mode/clike/clike.js    Sun Feb 22 23:10:18 2015
--- swimpc/commontest/CodeMirror/mode/clike/clike.js    Fri Mar 13 01:05:34 2015
***************
*** 48,58 ****
      if (ch == "/") {
        if (stream.eat("*")) {
          state.tokenize = tokenComment;
!         return tokenComment(stream, state);
        }
        if (stream.eat("/")) {
!         stream.skipToEnd();
!         return "comment";
        }
      }
      if (isOperatorChar.test(ch)) {
--- 48,61 ----
      if (ch == "/") {
        if (stream.eat("*")) {
          state.tokenize = tokenComment;
!         // JMO return tokenComment(stream, state);
!     return "comment";        // JMO
        }
        if (stream.eat("/")) {
!         // JMO stream.skipToEnd();
!         // JMO return "comment";
!     state.tokenize = tokenLineComment;    // JMO
!     return "comment";            // JMO
        }
      }
      if (isOperatorChar.test(ch)) {
***************
*** 87,101 ****
      };
    }
  
    function tokenComment(stream, state) {
      var maybeEnd = false, ch;
!     while (ch = stream.next()) {
        if (ch == "/" && maybeEnd) {
          state.tokenize = null;
          break;
        }
        maybeEnd = (ch == "*");
      }
      return "comment";
    }
  
--- 90,134 ----
      };
    }
  
+   function tokenLineComment(stream, state) {        // JMO
+       if(stream.eatWhile(/[^\w\$_\xa1-\uffff]/)) {    // JMO
+           if(stream.eol()) {            // JMO
+               state.tokenize = null;        // JMO
+           }                    // JMO
+         return "comment";            // JMO
+       }                        // JMO
+             if(stream.eatWhile(/[\w\$_\xa1-\uffff]/)) {    // JMO
+           if(stream.eol()) {            // JMO
+               state.tokenize = null;        // JMO
+         }                    // JMO
+               var cur = stream.current();        // JMO
+               if(cur == 'TODO' || cur == 'FIXME' || cur == 'XXX' || cur == 'HACK') {    // JMO
+                   return "commentHighlight";    // JMO
+               }                    // JMO
+           }                        // JMO
+           return "comment";                // JMO
+   }
+ 
    function tokenComment(stream, state) {
      var maybeEnd = false, ch;
!     // JMO while (ch = stream.next()) {
!     var ateSome = false;                // JMO
!     while (ch = stream.eat(/[^\w\$_\xa1-\uffff]/)) {    // JMO
!       ateSome = true;                    // JMO
        if (ch == "/" && maybeEnd) {
          state.tokenize = null;
          break;
        }
        maybeEnd = (ch == "*");
      }
+     if(ateSome) return "comment";            // JMO
+       
+     if(stream.eatWhile(/[\w\$_\xa1-\uffff]/)) {        // JMO
+           var cur = stream.current();            // JMO
+           if(cur == 'TODO' || cur == 'FIXME' || cur == 'XXX' || cur == 'HACK') {    // JMO
+           return "commentHighlight";        // JMO
+           }                        // JMO
+     }                            // JMO
      return "comment";
    }
  
diff -cbr CodeMirror-master/mode/properties/properties.js swimpc/commontest/CodeMirror/mode/properties/properties.js
*** CodeMirror-master/mode/properties/properties.js    Mon Jan 19 03:24:04 2015
--- swimpc/commontest/CodeMirror/mode/properties/properties.js    Thu Mar 12 11:29:27 2015
***************
*** 41,47 ****
  
        if (sol && (ch === "#" || ch === "!" || ch === ";")) {
          state.position = "comment";
!         stream.skipToEnd();
          return "comment";
        } else if (sol && ch === "[") {
          state.afterSection = true;
--- 41,59 ----
  
        if (sol && (ch === "#" || ch === "!" || ch === ";")) {
          state.position = "comment";
!         // stream.skipToEnd();
!         return "comment";
!       } else if(state.position === "comment") {
!           stream.backUp(1);                // JMO
!           if(stream.eatWhile(/[^A-Z]/)) {        // JMO
!               return "comment";
!           }
!           if(stream.eatWhile(/[A-Z]/)) {        // JMO
!                var cur = stream.current();        // JMO
!               if(cur == 'TODO' || cur == 'FIXME' || cur == 'XXX' || cur == 'HACK') {    // JMO
!                   return "commentHighlight";    // JMO
!               }                    // JMO
!           }
            return "comment";
        } else if (sol && ch === "[") {
          state.afterSection = true;