codemirror-vim
codemirror-vim copied to clipboard
Cursor moves past end of line in vim
Copied from https://github.com/codemirror/codemirror5/issues/5422:
To reproduce
- Open the vim demo.
- Enter
normal
mode. - Click past the end of a line.
Expected
Cursor should be over the last character in the line.
Actual
Cursor moves past the last character in the line.
Interestingly, if you move the cursor left, it goes to the correct position, and then it can't be moved right again, so it looks like CodeMirror already knows that this is an illegal position.
I'd like to help with a pull request, but I'm not sure where to start- any pointers would be appreciated :)
We noticed this too, and I believe it's leading to another bug where the cursor will flash the next character of the wrapped line:
Minimal reproduction in this CodeSandbox.
My guess is that this is because the cursor shouldn't be allowed in this position in the first place - as noted above, you cannot put the cursor here with the keyboard only - and therefore it's calculating the underlying character incorrectly.
i've scribbled up an small extension that patches this problem: codemirror.net/try.
i may contribute it to core here when i have time. the gist is the below:
EditorState.transactionFilter.of(tr => {
const { vim } = getCM(view).state
const insertMode = vim.insertMode
const { to: selectionTo, from: selectionFrom } = tr.newSelection.main
const noSelection = selectionTo === selectionFrom
const { from: lineFrom } = tr.newDoc.lineAt(tr.newSelection.main.from)
const { to: lineTo } = tr.newDoc.lineAt(tr.newSelection.main.to)
const isEmpty = lineTo === lineFrom
if (!isEmpty && noSelection && !insertMode && selectionTo >= lineTo) {
tr.newSelection.main.to = lineTo - 1
}
if (!isEmpty && noSelection && !insertMode && selectionFrom >= lineTo) {
tr.newSelection.main.from = lineTo - 1
}
return [tr]
}),
cheers! cc @nakulj and @40thieves.