Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Bug] Exiting Visual mode at end of line leaves the Normal-mode cursor past the final character

Aperta
#277 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
65/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
javascript, vim
Ambito
devtools

Direzione di ricerca

The bug is in the exitVisualMode function in packages/codemirror-vim-core/vim.js. Start by reading the reproduction steps and the provided code snippet to understand the cursor behavior. Examine the clipCursorToContent helper and how visual mode flags are cleared. The candidate fix shows the necessary reordering of operations. Test the fix with the provided minimal setup and check edge cases like empty lines and supplementary characters.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Related: #38 reports entering an invalid end-of-line cursor position by clicking with the mouse. This report reproduces a similar symptom entirely through Vim keys and identifies a separate path in exitVisualMode.

Versions and environment

  • @replit/codemirror-vim: 6.4.0
  • @replit/codemirror-vim-core: 0.1.0
  • @codemirror/state: 6.7.5
  • @codemirror/view: 6.43.12
  • Reproduced in native macOS WebKit, both with a bare CodeMirror editor and in an application integration.

Reproduction

  1. Start with a single line containing alpha, with the cursor on a in Normal mode.
  2. Press v, then press l five times to reach the position after the final character.
  3. Press Escape.
  4. Press l once more.

After step 3, the Normal-mode cursor remains at zero-based column 5, after the final a. Step 4 moves it backward to column 4 despite being a rightward motion.

Expected: Escape should leave the Normal-mode cursor at column 4 immediately, and the following l should not move it. Unconfigured Vim behaves this way.

Minimal setup and programmatic reproduction:

import { EditorView, drawSelection } from '@codemirror/view';
import { vim, Vim, getCM } from '@replit/codemirror-vim';

const view = new EditorView({
  doc: 'alpha',
  extensions: [vim(), drawSelection()],
  parent: document.body,
});

const cm = getCM(view);
for (const key of ['v', 'l', 'l', 'l', 'l', 'l', '<Esc>']) {
  Vim.handleKey(cm, key, 'user');
}
console.log(cm.getCursor()); // Actual: { line: 0, ch: 5 }; expected ch: 4
Vim.handleKey(cm, 'l', 'user');
console.log(cm.getCursor()); // { line: 0, ch: 4 }

Apparent cause and candidate fix

In packages/codemirror-vim-core/vim.js, exitVisualMode calls clipCursorToContent before clearing vim.visualMode. That helper permits the line-break position while Visual mode is active, so it uses Visual-mode bounds for the resulting Normal-mode cursor.

Moving the cursor-clipping block after clearing the Visual-mode flags corrects this reproduction. updateLastSelection must still run before clearing the flags so gv retains the previous selection:

function exitVisualMode(cm, moveHead) {
  var vim = cm.state.vim;
  updateLastSelection(cm, vim);
  vim.visualMode = false;
  vim.visualLine = false;
  vim.visualBlock = false;
  if (moveHead !== false) {
    cm.setCursor(clipCursorToContent(cm, vim.sel.head));
  }
  if (!vim.insertMode) CM.signal(cm, "vim-mode-change", {mode: "normal"});
}

Local checks with that change covered nonempty and empty lines, a supplementary-plane emoji, gv, visual yank, linewise put, and undo.

Lingua principale
JavaScript
Stelle
479
Fork
57
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di replit/codemirror-vim

Tutte le issue di replit/codemirror-vim

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.