Pressing enter deletes the following textmarker


Pressing enter will delete the following textmarker when the cursor is in the above position.How to prevent that?

    const marker = doc.markText(startPos, { line: endPos.line, ch: endPos.ch + 1 }, { 
            replacedWith: ele, 
            clearWhenEmpty: false,
            inclusiveLeft: false,
            inclusiveRight: false,
            clearOnEnter: false,
            atomic: true
        })

Insert mark using the above code

Can you provide the full (minimal) code that produces the situation? I have no idea what startPos and endPos are here.


Insert a node at the cursor and i want this node to behave like a single character

This is still not very helpful. Firstly, it’s easier to copy-paste code than to take a screenshot and post that, and that would allow me to copy the code to try it out. Secondly, you don’t appear to have made any effort to reduce the code to the minimal complexity needed to reproduce the issue. Thirdly, could it be that you’re reusing ele (which isn’t defined in the visible code) for different markers? If so, since DOM elements can only be in the document once, that might cause the old marker to disappear when a new one is added.

I write a demo to show you my problem.
I want to insert a node at the cursor and i hope this node behave like a single character.
But ,pressing the enter key while the cursor is in front of the inserted node deletes the following node.

Or can you tell me how to do it ?
thx!

import * as React from 'react';
import CodeMirror from 'codemirror'
import "../node_modules/codemirror/lib/codemirror.css"

interface Props {

}

export default class Mirror extends React.Component<Props> {

    private div: HTMLDivElement;
    private editor: CodeMirror.Editor;

    componentDidMount () {
        this.editor = CodeMirror(this.div, {
            lineWrapping: true
        })
    }

    inesrt () {
        const doc = this.editor.getDoc()
        const startPos = doc.getCursor('start')

        doc.markText(startPos, startPos, {
            replacedWith: this.genNode(), 
            clearWhenEmpty: false,
            collapsed: true,
            inclusiveLeft: false,
            inclusiveRight: false,
            clearOnEnter: false
         })
    }

    genNode () {
        const node = document.createElement('div')
        node.innerHTML = `<div>${Math.random().toString().slice(0, 5)}</div><div>${Math.random().toString().slice(0, 5)}</div>`;
        (node.children[0] as HTMLElement).style.cssText = 'background-color: red; line-height: 30px; display: inline-block';
        (node.children[1] as HTMLElement).style.cssText = 'background-color: blue;line-height: 30px; display: inline-block';

        node.style.cssText = 'border-radius: 50%; overflow: hidden;display: inline-block'

        return node
    }

    render () {
        return (
            <>
                <div ref={ele => { this.div = ele as HTMLDivElement }}></div>
                <button onClick={() => this.inesrt()}>insert</button>
            </>
        )
    }

}

If you set inclusiveRight to true, that should help.

I’ve tried this before, and this leads to several problems.

  1. When the cursor position is behind the inserted node, pressing the backspace key does not delete the node but the text before it
  2. If there is no text behind the inserted node, the cursor cannot move behind the node
  3. When the cursor is after the first character after the node is inserted, pressing the backspace key deletes the character and the node

I see. Well, you may be out of options then. A mark that’s inclusive on both sides is replaced when something is inserted at its position.

thx

If i don’t use mark, how else can i insert a node at the cursor and that node behave like a single character.

You could insert an actual character and cover it with a replacing mark.

Also, I think using setBookmark instead of markText to create the widget results in slightly different behavior, which might actually be what you want here.