ps0604
ps0604

Reputation: 1071

CodeMirror custom mode - how to apply styles on keywords?

I'm trying to write my own CodeMirror mode as documented here.

My objective is to change the color of specific keywords. For example, any "aaa" word needs to be red and any "bbb" word needs to be blue. Any other words need to have the default color.

This is my unsuccessful attempt (see jsfiddle). How to make this work?

HTML:

<textarea rows="4" cols="30" id="cm" name="cm">aaa bbb ccc</textarea>

CSS:

.style1 { color: red; }
.style2 { color: blue; }

Javascript:

CodeMirror.defineMode("mymode", function() {

  return {
    token: function(stream,state) {

        if (stream.match("aaa") ) {
            console.log("aaa found");
            while ((ch = stream.next()) != null)
                if (ch == " " && stream.next() == " ") break;
            return "style1";
        }
        else if (stream.match("bbb") ) {
            console.log("bbb found");
            while ((ch = stream.next()) != null)
                if (ch == " " && stream.next() == " ") break;   
            return "style2";
        }
     else
         return null;
    }
  };

});


var editor = CodeMirror.fromTextArea(document.getElementById('cm'), {
    mode: "mymode",
    lineNumbers: true
});  

Upvotes: 3

Views: 4587

Answers (1)

Marijn
Marijn

Reputation: 8929

You had two problems.

  • CodeMirror prefixed cm- to classes used to style tokens. The styles in your CSS have to account for that.

  • You were skipping the rest of the line after finding "aaa" or "bbb", althrough your description of your goal sounds like you didn't want to do that.

I've fixed both in the jsfiddle. You may also want to only match full words (currently fooaaabar also has aaa highlighted). To do that, first have your tokenizer read a whole word (stream.eatWhile(/\w/)), and then see if the resulting word is one of the words you are looking for (stream.current() == "aaa").

Upvotes: 12

Related Questions