Динамически обновлять правила режима подсветки синтаксиса для редактора Ace.

Совершенно новый для ace editor dev динамически добавлять дополнительные правила в файл режима для подсветки синтаксиса. Я делаю вызов 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

«Если вы действительно хотите сохранить глобальную переменную, вы можете обернуть все в функцию, вызвать эту функцию, чтобы получить обновленный конструктор режима, а затем вызвать setMode (новый режим)».

Я не знаю, как это сделать, и любая помощь будет оценена по достоинству.

У кого-нибудь есть методы динамического обновления правил подсветки синтаксиса редактора ace?


person zaf    schedule 04.03.2014    source источник


Ответы (1)


См. 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.

person a user    schedule 04.03.2014
comment
Спасибо. Я проверю оба метода, как только смогу, и отчитаюсь. - person zaf; 04.03.2014
comment
Добавление опции с датой работает. Я проверю другой метод, когда у меня будет больше времени. Ваше здоровье. - person zaf; 05.03.2014
comment
Можно ли использовать это для изменения ключевых слов в ace/mode/javascript? - person techdog; 07.04.2015
comment
У меня аналогичная настройка, но после bgTokenizer.start(0) представление не обновляется правильно. Подсветка по-прежнему выделяет первоначальные правила, но автозаполнение правильно определяет новые ключевые слова из нового набора правил. Что мне не хватает? - person ivanhoe1982; 27.07.2015
comment
покажите пожалуйста страницу с ошибкой, без этого невозможно понять что вы упускаете - person a user; 27.07.2015
comment
Заменяет ли пример jsbin исходный режим или добавляет к нему. Как бы вы начали с выделения javascript и добавили динамические слова к выделению javascript? - person techdog; 02.10.2016
comment
@techdog, вам нужно изменить исходный код режима. Почему вы хотите добавить динамические слова в javascript? может быть другой способ добиться того же эффекта - person a user; 02.10.2016
comment
В моей ситуации пользователь может создать несколько пользовательских объектов, которые я хотел бы выделить вместе с обычной подсветкой javascript. В jsbin кажется, что динамический режим заменяет исходный режим, поэтому выделяются только динамические слова. - person techdog; 04.10.2016
comment
Кто-нибудь знает, как сделать jsbin исправления Date.now, добавив некоторые пользовательские ключевые слова в javascript? - person techdog; 06.10.2016
comment
я думаю, вам нужно скопировать режим js и изменить его - person a user; 06.10.2016
comment
Он перезаписывает существующие правила выделения. Я пробовал с режимом Python и python_highlight_rules. После добавления этого кода он не дает мне подсветку синтаксиса для ключевых слов, операторов и т. д. Python. Есть ли способ не перезаписывать существующие правила выделения? - person smita chougale; 17.10.2018
comment
Первое предложение сработало для меня после импорта необходимых режимов, например: import 'brace/mode/plain_text'; - person Albena Kertova; 03.12.2020