After using the addLineWidget method to add multiple LineWidgets and CodeMirror fixed heights, a serious error occurred in the cursor positioning. getScrollInfo and scrollTo are used for processing, but unfortunately they do not take effect.

.CodeMirror {
   height: 400px;
}
const initialValue = `# Markdown Editor

Write in markdown, and evaluate code in the code blocks. Currently only JavaScript is supported.

\`\`\`js
console.log("hi~");
\`\`\`
`
this.infoContent = ''

let addLineWidgetWithType = (line, addType) => {
  var info = cm.getScrollInfo();
  var after = cm.charCoords({line: cm.getCursor().line + 1, ch: 0}, "local").top;
  if (info.top + info.clientHeight < after)
    cm.scrollTo(null, after - info.clientHeight +0);
  if (addType === 'error') addLineMake(line, 'error')
  let widgets = cm.lineInfo(line).widgets
  if (widgets) {
    for (var i = 0; i < widgets.length; ++i) {
      if (widgets[i].node.className.includes(addType)) return false
    }
  }

  let isQuestionBegin = addType === 'questionBegin'
  let node = document.createElement(isQuestionBegin ? 'hr' : 'div')
  node.className = `smb-cm-widget ${addType}`
  node.innerHTML = isQuestionBegin ? '' : this.infoContent
  cm.addLineWidget(line, node, { above: isQuestionBegin })
}

let removeLineWidgets = (line, withBegin = false) => {
  let widgets = cm.lineInfo(line).widgets
  if (!widgets) return
  for (var i = 0; i < widgets.length; ++i) {
    if (widgets[i].node.className.includes('questionBegin')) {
      if (withBegin) widgets[i].clear()
    } else {
      widgets[i].clear()
    }
  }
}
let isQuestionBegin = (lineText) => {
  let questionBegin = questionBeginReg.exec(lineText)
  return questionBegin
}

var cm = CodeMirror(document.querySelector('#mount'), {
  theme: 'default',
  matchBrackets: true,
  maxLength: 4000,
  indentUnit: 2,
  tabSize: 2,
  smartIndent: true,
  lineNumbers: true,
  lineWrapping: true,
  gutters: ['CodeMirror-linenumbers', 'CodeMirror-other-make'],
})

const questionBeginReg = /^\s*(\d+)[\..。、\::、\s\/\\\))]+(?:(?:\[|【|「)(.*?)(?:\]|」|】))?(.*)$/

cm.on('change', (cm, change) => {
  for (var line = 0; line <= cm.lastLine(); line++) {
    removeLineWidgets(line, true)

    let lineText = cm.getLine(line)
    let questionBegin = isQuestionBegin(lineText)
    if (questionBegin) {
      addLineWidgetWithType(line, 'questionBegin')
    }
  }
})

Copy the above JavaScript code and style can be reproduced here: https://codepen.io/mtso/pen/LzqKNN

I don’t see a scrollbar problem in your demo. You’re going to have to be more specific.

@marijn This is a demo that can be reproduced completely. When the total number of rows exceeds 20 and the scroll bar is not at the top, continue typing or press Enter to reproduce it perfectly.
The premise is that it must be entered in the first 2 lines

1.qeustion desc
2.qeustion desc

Content like this

When there are more lines that satisfy the regularity, the position of the cursor and scroll bar is more wrong
/^\s*(\d+)[\.. . , \::, \s\/\\\))]+(?:(?:\[|[|「)(.*?)(?:\]|」|】))?(.*) $/

Today I also tried this demo Inline Widget Demo
, after adding the line widget, the cursor will be positioned incorrectly until the scroll bar appears

In fact, I have been troubled by this problem for a week :frowning:

Still not seeing this, neither on Chrome nor Firefox.

I found this problem on codepen, can’t this demo reproduce the problem?

.CodeMirror {
   height: 100px;
}
const questionBeginReg = /^\s*(\d+)[\..。、\::、\s\/\\\))]+(?:(?:\[|【|「)(.*?)(?:\]|」|】))?(.*)$/

let isQuestionBegin = (lineText) => {
  let questionBegin = questionBeginReg.exec(lineText)
  return questionBegin
}

let addLineWidgetWithType = (line, addType) => {
  let widgets = cm.lineInfo(line).widgets
  if (widgets) {
    for (var i = 0; i < widgets.length; ++i) {
      if (widgets[i].node.className.includes(addType)) return false
    }
  }

  let node = document.createElement('hr')
  node.className = 'questionBegin'
  let lineWidget = cm.addLineWidget(line, node, { above: true })
  lineWidget.changed()
}

let removeLineWidgets = (line) => {
  let widgets = cm.lineInfo(line).widgets
  if (!widgets) return
  for (var i = 0; i < widgets.length; ++i) {
    widgets[i].clear()
  }
}

let checkLine = (cm) => {
  for (var line = 0; line <= cm.lastLine(); line++) {
    removeLineWidgets(line)
    if (isQuestionBegin(cm.getLine(line))) {
      addLineWidgetWithType(line, 'question-begin')
    }
  }
}

let content = `
1.testsssss

1.testsss
1.test

plz
xxxx
....
..
`

var cm = CodeMirror(document.querySelector('.editorContainer'), {
  theme:'default',
  maxLength: 4000,
  lineNumbers: true,
  gutters: ['CodeMirror-linenumbers','CodeMirror-other-make'],
  value: content,
})

cm.on('change', (cm, change) => {
  checkLine(cm)
})

checkLine(cm)

This demo (demo) ensures that you can reproduce this problem, excuse me, please take a look again, thank you


It seems that the problem is that the line widget is added, which causes the scroll height to be incorrect, and then when inputting content, the cursor is positioned incorrectly

And your scroll bar cannot be at the top position

I’m really done going in circles on this. Still not seeing the problem on that last link, and you still haven’t told me which browser you’re testing with.

I see this as well. Below is my screen capture. I just scroll to the end of the document, and type one character at the end of the line with “xxx” in it, the document scrolls up, then I scroll down again and type one more character, etc. I am on the latest Chrome, on OSX. HTH.

Kapture 2021-12-03 at 15.23.22

I’m really sorry, I’m using the chorme 96 , as the friend above said, when typing at the bottom of the document, it will scroll up.
Firefox is also the latest, and this problem is the same. In addition, my CodeMirror version is 5.48.2

A Pen by Mr.Ran (1)