Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic syntax highlighting #4076

Closed
jaa134 opened this issue Sep 25, 2019 · 4 comments
Closed

Dynamic syntax highlighting #4076

jaa134 opened this issue Sep 25, 2019 · 4 comments

Comments

@jaa134
Copy link

jaa134 commented Sep 25, 2019

Hi,

I'd like to add a list of custom keywords to a mode. Ive found this issue here (#3905), but I'm instead looking for a solution that is NOT syntax aware. That is to highlight all instances of the word (red) even if it is inside a string or a comment. It seems like the solution that @nightwing shared highlights the added keywords even when in a string, but keeps them the same color as the string. I'd like to use a different color. Here's an example of what I'd like. Does the ace editor currently support this behavior?

Bonus: Can we supply additional keywords as a regex pattern?

@YellowAfterlife
Copy link
Contributor

At the very least you could add a new rule (with a regex for your additional keywords) to front of each tokenizer state so that it matches before anything usually would.

@jaa134
Copy link
Author

jaa134 commented Oct 8, 2019

@YellowAfterlife Thanks for the response! I came up with something like this:

// initialize editor
this.editor = ace.edit(this.editorId);
var session = this.editor.session;
session.setMode(`ace/mode/${this.language || 'sh'}`);

// update the rule set to match my rules first
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: '\\${p:.+}|\\${p\\?:.+}'
        });
    }
}

// force recreation of tokenizer
session.$mode.$tokenizer = null;
session.bgTokenizer.setTokenizer(session.$mode.getTokenizer());
// force re-highlight whole document
session.bgTokenizer.start(0);

This is so close to working! However, it seems as if the last line doesn't do anything because the document isn't actually re-highlighted until the second load of the editor. I've been able to fix this by setting a temporary mode and then setting the mode again back to the intended mode. This seems to force the editor to re-highlight. Like this:

session.setMode('ace/mode/text');
session.setMode(`ace/mode/${this.language || 'sh'}`);

What am I missing? I don't really want to rely on setting the mode 3 times.

@nightwing
Copy link
Member

Most likely this happens because setMode is async for modes that are not loaded yet, so the code updating the rules adds new rules to the text mode instead of the new mode., try using the callback to the .setMode

session.setMode(`ace/mode/${this.language || 'sh'}`, 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: 'FLIGHTINFO|\\${p:.+}|\\${p\\?:.+}'
            });
        }
    }
    // force recreation of tokenizer
    session.$mode.$tokenizer = null;
    session.bgTokenizer.setTokenizer(session.$mode.getTokenizer());
    // force re-highlight whole document
    session.bgTokenizer.start(0);
});

@jaa134
Copy link
Author

jaa134 commented Oct 8, 2019

@nightwing @YellowAfterlife I was able to verify this was the problem. To all others who have this problem, you can use my original solution and pass it as a callback to Session.setmode. Thank you both for your help! I'm going to close this now.

@jaa134 jaa134 closed this as completed Oct 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants