Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor moves past end of line in vim #38

Open
nakulj opened this issue Jul 19, 2022 · 2 comments
Open

Cursor moves past end of line in vim #38

nakulj opened this issue Jul 19, 2022 · 2 comments

Comments

@nakulj
Copy link

nakulj commented Jul 19, 2022

Copied from codemirror/codemirror5#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.
expected

Actual

Cursor moves past the last character in the line.
actual
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 :)

@40thieves
Copy link

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:

Screen capture of clicking on the space at the end of a wrapped line which then starts flashing 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.

@robinplace
Copy link

robinplace commented Jan 19, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants