动态更新Ace编辑器的语法突出显示模式规则

时间:2014-03-04 08:39:40

标签: javascript requirejs syntax-highlighting ace-editor

ace编辑器开发人员的新手,为模式文件动态添加其他规则以进行语法突出显示我正在进行ajax调用,该调用设置模式文件中可用的全局变量进行处理。

这是设置和初始ajax调用:

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");
});

使用以下内容修补模式文件:

// 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);

首次加载页面时,ace编辑器将所有关键字加到语法高亮显示中。这很有效。

问题是我们在某些事件发生时会更改规则,并希望ace编辑器刷新其语法规则。

再次执行ajax调用并且调用setMode什么都不做 - 这是因为要求js不重新加载文件。

我在GitHub上发布了一个没有解决方案的问题:

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

  

“如果你真的想保留全局变量,你可以包装所有内容   在一个函数中,调用该函数来获取更新的Mode构造函数,以及   然后调用setMode(新模式)。“

我不知道该怎么做,任何帮助都会受到赞赏。

有关如何动态更新ace编辑器语法突出显示规则的技术的任何人?

1 个答案:

答案 0 :(得分:15)

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

setMode缓存模式,除非他们有选项 所以你可以打电话

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

强制它创建新模式。

另一种方法是做

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()
};

然后每当高亮规则改变时

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

请参阅http://jsbin.com/ojijeb/445/edit