Breakpoints in CM6?

Hello, I’m currently trying to implement a breakpoint system and was trying to use the old breakpoint demo as a starting point. I’m afraid, however, that it is just not possible to do that easily.

This is the CM5 Code sample from the demo:

var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
  lineNumbers: true,
  gutters: ["CodeMirror-linenumbers", "breakpoints"]
});
editor.on("gutterClick", function(cm, n) {
  var info = cm.lineInfo(n);
  cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
});

function makeMarker() {
  var marker = document.createElement("div");
  marker.style.color = "#822";
  marker.innerHTML = "●";
  return marker;
}

This is what I have so far in CM6. My Problem is that I don’t know how to make the markers move with the document and I’m also not sure whether this is the right way to go in general.

If anyone here could point me in the right direction, I’d be grateful.

My code so far:

import {lineNumbers, gutter, GutterMarker} from '@codemirror/gutter';

class BreakMarker extends GutterMarker {
  constructor(show) {
    super();
    this.show = show;
  }

  eq(other) {return false;}
  toDOM() {
    var el = document.createElement('span');
    el.setAttribute("class",this.show ? "active" : "");
    el.innerText = this.show ? "⬤" : "•";
    return el;
  }
}
var breakpoints = {};
export const breakPointGutter = gutter({
  class: "ap-breakpoints",
  renderEmptyElements: true,
  domEventHandlers: {
    click: (view, line) => {
      var num = view.state.doc.lineAt(line.from).number;
      breakpoints[num] = !breakpoints[num];

      var changespec = {from: line.from, to: line.to};
      var updated = view.state.update([{changes: changespec}]);
      view.dispatch(updated);
    }
  },
  lineMarker(view, line) {
    var num = view.state.doc.lineAt(line.from).number;
    return new BreakMarker(!!breakpoints[num]);
  }
})

You’ll want to return this.show == other.show from the eq method (no need to redraw markers when they don’t change).

And though you didn’t tell us what is going wrong with your code, I guess the problem is related to the updating of markers. You’ll want to keep breakpoints in your editor state and update it (in a copying/immutable way) with a state effect, so that editor updates are kept in sync with marker updates.

Hi, Tried codemirror v6 code to implement line breakpoints, My code looks like this -

import {gutter, GutterMarker} from '@codemirror/view';

class BreakMarker extends GutterMarker {
  constructor(show) {
    super();
    this.show = show;
  }

  eq(other) {return false;}
  toDOM() {
    var el = document.createElement('span');
    el.setAttribute("class",this.show ? "active" : "");
    el.innerText = this.show ? "⬤" : "•";
    return el;
  }
}
var breakpoints = {};
export const breakPointGutter = gutter({
  class: "ap-breakpoints",
  renderEmptyElements: true,
  domEventHandlers: {
    click: (view, line) => {
      var num = view.state.doc.lineAt(line.from).number;
      breakpoints[num] = !breakpoints[num];

      var changespec = {from: line.from, to: line.to};
      var updated = view.state.update([{changes: changespec}]);
      view.dispatch(updated);
    }
  },
  lineMarker(view, line) {
    var num = view.state.doc.lineAt(line.from).number;
    return new BreakMarker(!!breakpoints[num]);
  }
})

So, when I’m clicking on the gutter, breakpoint is not appearing. Instead, I click on gutter and then click on any line in document then breakpoint is appearing. Don’t know whats going wrong and how to fix it.

Your click handler appears to be dispatching a transaction that deletes the clicked line (and changing the plugin state as a side effect). You’ll want to dispatch some effect that tells your plugin to change its state instead, and make the state change in the update method.

Also eq(other) {return false;} is a terrible idea that will cause a lot of unnecessary marker redrawing.

I’ve added this to the domEventHandlers and it worked

    lineMarkerChange: (update: ViewUpdate): boolean => {
        return true;
      },