Creating new modes for CodeMirror

2019-04-06 00:36发布

I want to highlight only keywords that look like this: {KEYWORD} (basically UPPERCASE words wrapped between single {} parentheses)

I tried this by copying the code from the Mustache Overlay demo, and by replacing the double brackets with single ones:

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

but it doesn't work very good :)

Any ideas?

2条回答
在下西门庆
2楼-- · 2019-04-06 01:12

There is special handling in the Mustache example because it needs to handle 2-character delimiters (e.g. there are two characters in '{{' and '}}'). I've never used CodeMirror before, so this is just a guess, but try something like this:

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

Edit

it works (though it highlights words with lowercase letters too)

This should work:

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;
}
查看更多
三岁会撩人
3楼-- · 2019-04-06 01:35

Accepted answer highlight every chars in brackets.

enter image description here

My version, if someone else encounter same issue.

enter image description here

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;
        }
    };
});
查看更多
登录 后发表回答