Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add new highlight rules at runtime with Ace Code Editor?

I'm trying to inject custom keywords into whatever mode is set on the editor. I have tried the following:

rules = editor.session.getMode().$highlightRules
startRules = rules.$rules.start

startRules.push({
  regex: "\\w+"
  onMatch: rules.createKeywordMapper({customToken: "one|two"})
})

rules.addRules({start: startRules})

editor.session.bgTokenizer.start(0)

What I'm trying to accomplish is to be able to write in the word "two" and have it be wrapped around a custom token

like image 277
Jason M Avatar asked Sep 06 '16 15:09

Jason M


1 Answers

I'm a few years late, but I found a solution recently that might help you and others. Check out this issue I opened on their Github repo (Ace Editor Repo). Using this solution, you can define your own token like I have at runtime. In my example, I made a token called "my_token". The editor will wrap this in a div with a class name that matches your token name prefixed with "ace_". So something like "ace_my_token".

Be aware that part of my solution required me to highlight my new rule with highest priority as I needed it to highlight differently even when within a string which is why I put it first in the rule set. You may need to adjust where you insert your rule depending on how you want it highlighted.

this.editor = ace.edit(this.editorId);
var session = this.editor.session;
this.language = this.language || 'text';
session.setMode('ace/mode/' + this.language, function() {
    var rules = session.$mode.$highlightRules.getRules();
    for (var stateName in rules) {
        if (Object.prototype.hasOwnProperty.call(rules, stateName)) {
            rules[stateName].unshift({
                token: 'my_token',
                regex: 'two'
            });
        }
    }
    // force recreation of tokenizer
    session.$mode.$tokenizer = null;
    session.bgTokenizer.setTokenizer(session.$mode.getTokenizer());
    // force re-highlight whole document
    session.bgTokenizer.start(0);
});

Here's a demo: https://jsbin.com/yogeqewehu/edit?html,css,console,output

like image 151
Jacob Avatar answered Oct 16 '22 23:10

Jacob