Создание новых режимов для CodeMirror

Я хочу выделить только те ключевые слова, которые выглядят так: {KEYWORD} (в основном слова в ЗАГЛАВНЫХ РЕГИСТРАХ, заключенные в одинарные скобки {})

Я попробовал это, скопировав код из демонстрации наложения усов и заменив двойные скобки одинарными те:

CodeMirror.defineMode('mymode', function(config, parserConfig) {
  var mymodeOverlay = {
    token: function(stream, state) {
      if (stream.match("{")) {
        while ((ch = stream.next()) != null)
          if (ch == "}" && stream.next() == "}") break;
        return 'mymode';
      }
      while (stream.next() != null && !stream.match("{", false)) {}
      return null;
    }
  };
  return CodeMirror.overlayParser(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mymodeOverlay);
});

но это не очень хорошо работает :)

Любые идеи?


person Alex    schedule 15.06.2011    source источник
comment
Каким образом это не работает?   -  person Matt Ball    schedule 16.06.2011
comment
хорошо, он выделяет все от { до конца строки (и это не чувствительно к регистру)   -  person Alex    schedule 16.06.2011


Ответы (2)


В примере с усами есть специальная обработка, потому что он должен обрабатывать 2-символьные разделители (например, в '{{' и '}}' есть два символа). Я никогда раньше не использовал CodeMirror, так что это всего лишь предположение, но попробуйте что-то вроде этого:

CodeMirror.defineMode("mymode", function(config, parserConfig) {
  var mymodeOverlay = {
    token: function(stream, state) {
      if (stream.match("{")) {
        while ((ch = stream.next()) != null)
          if (ch == "}") break;
        return "mymode";
      }
      while (stream.next() != null && !stream.match("{", false)) {}
      return null;
    }
  };
  return CodeMirror.overlayParser(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mymodeOverlay);
});

Редактировать

он работает (хотя он также выделяет слова строчными буквами)

Это должно работать:

token: function(stream, state) {
  if (stream.match("{")) {
    while ((ch = stream.next()) != null && ch === ch.toUpperCase())
      if (ch == "}") break;
    return "mymode";
  }
  while (stream.next() != null && !stream.match("{", false)) {}
  return null;
}
person Matt Ball    schedule 15.06.2011
comment
он работает (хотя и выделяет слова строчными буквами). спасибо :р - person Alex; 16.06.2011
comment
Извините, я полностью пропустил часть о совпадении только слов в верхнем регистре. Смотрите мою правку. - person Matt Ball; 16.06.2011

Принятый ответ выделите все символы в скобках.

введите здесь описание изображения

Моя версия, если кто-то еще столкнется с такой же проблемой.

введите здесь описание изображения

CodeMirror.defineMode('mymode', function (config, parserConfig) {
    return {
        /**
         * @param {CodeMirror.StringStream} stream
         */
        token: function (stream) {
            // check for {
            if (stream.match('{')) {
                // trying to find }

                // if not a char
                if (!stream.eatWhile(/[\w]/)) {
                    return null;
                }

                if (stream.match('}')) {
                    return 'mymode';
                }
            }

            while (stream.next() && !stream.match('{', false)) {}

            return null;
        }
    };
});
person Alexey B.    schedule 13.10.2014