ACE Editor addMarker

There is some problem with marker positioning!

by 0xcoder

HTML

<script src="https://unpkg.com/[email protected]/lib/index.js"></script>
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Demo - ACE Code Highlight</title>
    <script src="https://pagecdn.io/lib/ace/1.4.12/ace.js" crossorigin="anonymous" integrity="sha256-Q9hnBpgBFstzZOr+OKFOWZWfcF5nFXO8Qz48Nmndo6U=" ></script>
  </head>
<body>

<div id="editor">var foo = \u001b[38;5;196mThisIsHighlighted(bar)\u001b[48;5;226m;

const CustomHighlightRules = function CustomHighlightRules(options) {
    \u001b[38;5;196mlet customRules = [
        {
            token: "keyword",
            regex: "my_keyword"
        }
    ];\u001b[48;5;226m

    let JSRules = new JavaScriptHighlightRules({jsx: (options && options.jsx)}).getRules();

    JSRules.no_regex = customRules.concat(JSRules.no_regex);
    this.$rules = JSRules;
}

var bar = ThisIsHighlighted(bar);</div>

</body>
</html>

CSS

#editor {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

JavaScript

define('AnsiHighlightRules', [], function (require, exports, module) {
  const oop = require('ace/lib/oop');
  const { EventEmitter } = require('ace/lib/event_emitter');
  const { Tokenizer } = require('ace/tokenizer');

  /**
   * Ansi highlight constructor, singleton to prevent the initialization
   * of multiple copies.
   *
   * @param {*} editor An instance of ACE editor
   * @returns null
   */
  const AnsiHighlight = function (editor) {
    if (editor.ansiHighlight) {
      return editor.ansiHighlight;
    }
    editor.ansiHighlight = this;
    this.$removeAnsiCodes = this.removeAnsiCodes.bind(this);
    this.attach(editor);
  };

  (function () {
    oop.implement(this, EventEmitter);

    this.attach = function (editor) {
      this.editor = editor;
      this.editor.commands.on('afterExec', this.$removeAnsiCodes);
    };

    this.detach = function () {
      this.editor = null;
      this.editor.commands.removeListener('afterExec', this.$removeAnsiCodes);
    };

    this.getTokenizer = function () {
      return AnsiHighlight.$tokenizer || this.createTokenizer();
    };

    this.createTokenizer = function () {
      AnsiHighlight.$tokenizer = new Tokenizer({
        start: [
          {
            token: 'custom_highlight',
            start: /\\u001b\[.*?m/,
            end: /\\u001b\[.*?m/,
          },
        ],
      });
      return AnsiHighlight.$tokenizer;
    };

    this.removeAnsiCodes = function () {
      const textLayer = this.editor.renderer.$textLayer;
      const renderToken = textLayer.$renderToken;

      textLayer.$renderToken = function (builder, col, token, value) {
        // Remove ansi codes from tokens
        const newValue = value.replace(/\\u001b\[.*?m/g, '');
        const newToken = {
          type: token.type,
          value: newValue,
        };
        col = renderToken.call(this, builder, col, newToken, newValue);

        return col;
      };
    };
  }).call(AnsiHighlight.prototype);

 ...