最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically update syntax highlighting mode rules for the Ace Editor - Stack Overflow

programmeradmin1浏览0评论

Totally new to ace editor dev, to dynamically add additional rules to a mode file for syntax highlighting I'm doing an ajax call that sets a global variable that is available inside the mode file to process.

Here is the setup and initial ajax call:

var editor = ace.edit("editor");

$.ajax({
  url: "json-mode-rules.php",
  dataType: "json"
}).done(function(data) {
    window.myModeRules=data; // ("foo","bar","etc")
    editor.getSession().setMode("ace/mode/python");
});

The mode file is patched with the following:

// keywords has already been initialised as an array
// e.g. var keywords = ("and|as|assert...etc")
var extraRules=window.codebenderModeLibrary["myModeRules"].join("|");
keywords=(keywords[0]+"|"+ extraRules);

When the page is loaded initallly the ace editor gets all the keywords to syntax highlight. This works great.

The issue is that we have the rules changing when certain events occur and would like the ace editor to refresh its syntax rules.

Doing the ajax call again and calling setMode does nothing - this is due to require js not reloading the file.

I have posted an issue on GitHub without a resolution yet:

"If you really want to keep global variable, you can wrap everything in a function, call that function to get updated Mode constructor, and then call setMode(new Mode)."

I don't know how to do that and any help would be appreciated.

Anyone with techniques on how to dynamically update ace editor syntax highlighting rules?

Totally new to ace editor dev, to dynamically add additional rules to a mode file for syntax highlighting I'm doing an ajax call that sets a global variable that is available inside the mode file to process.

Here is the setup and initial ajax call:

var editor = ace.edit("editor");

$.ajax({
  url: "json-mode-rules.php",
  dataType: "json"
}).done(function(data) {
    window.myModeRules=data; // ("foo","bar","etc")
    editor.getSession().setMode("ace/mode/python");
});

The mode file is patched with the following:

// keywords has already been initialised as an array
// e.g. var keywords = ("and|as|assert...etc")
var extraRules=window.codebenderModeLibrary["myModeRules"].join("|");
keywords=(keywords[0]+"|"+ extraRules);

When the page is loaded initallly the ace editor gets all the keywords to syntax highlight. This works great.

The issue is that we have the rules changing when certain events occur and would like the ace editor to refresh its syntax rules.

Doing the ajax call again and calling setMode does nothing - this is due to require js not reloading the file.

I have posted an issue on GitHub without a resolution yet:

https://github.com/ajaxorg/ace/issues/1835

"If you really want to keep global variable, you can wrap everything in a function, call that function to get updated Mode constructor, and then call setMode(new Mode)."

I don't know how to do that and any help would be appreciated.

Anyone with techniques on how to dynamically update ace editor syntax highlighting rules?

Share Improve this question edited Mar 4, 2014 at 8:44 zaf asked Mar 4, 2014 at 8:39 zafzaf 23.2k12 gold badges68 silver badges96 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 17

See https://github.com/ajaxorg/ace/blob/9cbcfb35d3/lib/ace/edit_session.js#L888

setMode caches modes, unless they have options so you can call

session.setMode({
   path: "ace/mode/python",
   v: Date.now() 
})

to force it to create a new mode.

Another way is to do

var DynHighlightRules = function() {
   // add function to change keywords
   this.setKeywords = function(kwMap) {
       this.keywordRule.onMatch = this.createKeywordMapper(kwMap, "identifier")
   }
   this.keywordRule = {
       regex : "\\w+",
       onMatch : function() {return "text"}
   }

   this.$rules = {
        "start" : [
            {
                token: "string",
                start: '"', 
                end: '"',
                next: [{ token : "language.escape", regex : /\\[tn"\\]/}]
            },
            this.keywordRule
        ]
   };
   this.normalizeRules()
};

and then whenever highlight rules change do

// update keywords
editor.session.$mode.$highlightRules.setKeywords({"keyword": "foo|bar|baz"})
// force rehighlight whole document
editor.session.bgTokenizer.start(0)

see http://jsbin.com/ojijeb/445/edit

发布评论

评论列表(0)

  1. 暂无评论