Is this the correct way to implement?

Hi my usecase is that I have two function which will be exposed which are addHighlight and clearHighlights what addHighlight does is takes from and to and highlights that part and also I need to make highlighted part atomic , for which i am using atomicExtension , and clearHighlights will remove the highlight once the highlighted text is deleted

Below is my implementation , which is working fine ( except for after highligting when I press space the highlight colour is extented ,and probably on next render it is going back to word)

I wanted to ask is this the correct implementation or there are any other good approach to achieve this? And how can we fix the above mentioned bug

const addHighlightEffect = StateEffect.define<{
  from: number;
  to: number;
  className: string;
  atomic: boolean;
}>();

const removeHighlightEffect = StateEffect.define<{
  className: string;
}>();

const highlightExtension = StateField.define<DecorationSet>({
  create() {
    return Decoration.none;
  },
  update(decorations, transaction) {
    decorations = decorations.map(transaction.changes);
    for (const effect of transaction.effects) {
      if (effect.is(addHighlightEffect)) {
        const { from, to, className, atomic } = effect.value;
        const decoration = Decoration.mark({
          class: className,
          inclusive: true,
          atomic,
        }).range(from, to);
        decorations = decorations.update({ add: [decoration] });
      } else if (effect.is(removeHighlightEffect)) {
        const { className } = effect.value;
        decorations = decorations.update({
          filter: (from, to, value) => {
            return !value.spec.class.includes(className);
          },
        });
      }
    }
    return decorations;
  },
  provide: (field) => EditorView.decorations.from(field),
});

const atomicExtension = EditorView.atomicRanges.of((view: EditorView) => {
  const decorations = view.state.field(highlightExtension, false);
  if (!decorations) {
    return RangeSet.empty;
  }

  const ranges: { from: number; to: number; value: Decoration }[] = [];
  decorations.between(0, view.state.doc.length, (from, to, value) => {
    if (value.spec?.class && value.spec?.atomic) {
      ranges.push({ from, to, value });
    }
  });

  return RangeSet.of(
    ranges.map(({ from, to, value }) => ({ from, to, value })),
    false,
  );
});

And this is how I am using the above mentioned function

addHighlight: (
          type,
          { columnStart, columnEnd, lineStart, lineEnd },
        ) => {
          const state = view.state;

          const from = state.doc.line(lineStart + 1).from + columnStart;
          const to = state.doc.line(lineEnd + 1).from + columnEnd;

          view.dispatch({
            effects: addHighlightEffect.of({
              from,
              to,
              className: classes[type],
              atomic: type === 'parameter',
            }),
          });

          view.dispatch({
            selection: EditorSelection.cursor(to),
            scrollIntoView: true,
          });
        },

        clearHighlights: (type) => {
          view.dispatch({
            effects: removeHighlightEffect.of({
              className: classes[type],
            }),
          });
        },

Sounds like you want inclusive: false instead.

Thanks @marjin , That worked ( My bad I missed that :frowning: ), Can you also please comment on this