[Bug] Exiting Visual mode at end of line leaves the Normal-mode cursor past the final character
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 65/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- javascript, vim
- 领域
- devtools
调研方向
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.
由索引模型根据 Issue 内容生成。
描述
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
- Start with a single line containing
alpha, with the cursor onain Normal mode. - Press
v, then presslfive times to reach the position after the final character. - Press Escape.
- Press
lonce 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.
- 主要语言
- JavaScript
- 星标
- 477
- 派生
- 55
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 没有贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
replit/codemirror-vim 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 50/100
replit/codemirror-vim#276 ·
-
Curly Brace deletion behaving unexpectedly可能已有人在做 @deepanshupal 于 16 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 68/100
replit/codemirror-vim#264 ·
-
`vim-mode-change` not fired on command mode enter/exit可能已有人在做 @oller 于 2 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 55/100
replit/codemirror-vim#251 · 1 条评论 ·
-
难度 4/5 3-5 天 新手友好度 45/100
replit/codemirror-vim#243 ·
-
难度 4/5 3-5 天 新手友好度 35/100
replit/codemirror-vim#239 ·
查看 replit/codemirror-vim 的全部 Issue
相似的 Issue
-
idnits3
难度 2/5 1-3 小时 新手友好度 76/100
ietf-tools/idnits#363 ·
维护者通常 1 天内回复
-
prototype(verifier_token): map disallowed warning to contraindicated before composite precedence check可能已有人在做 @drk-ram 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
agentrust-io/trace-spec#582 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 半天 新手友好度 72/100
TheOdinProject/curriculum#31479 ·
维护者通常 1 天内回复
-
chore
难度 2/5 1-3 小时 新手友好度 76/100
SignalK/n2k-signalk#368 ·
维护者通常 1 天内回复