Skip to content

fix(cli): join previous line when Ctrl+U pressed at column 0 - #5011

Merged
yiliang114 merged 2 commits into
QwenLM:mainfrom
ZijianZhang989:fix/ctrl-u-join-previous-line
Jun 12, 2026
Merged

fix(cli): join previous line when Ctrl+U pressed at column 0#5011
yiliang114 merged 2 commits into
QwenLM:mainfrom
ZijianZhang989:fix/ctrl-u-join-previous-line

Conversation

@ZijianZhang989

@ZijianZhang989 ZijianZhang989 commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Fixes Ctrl+U (kill_line_left) so that when the cursor is at column 0 (beginning of a line) and not on the first line, it joins the current line with the previous line, moving the cursor to the end of the previous line. Previously, pressing Ctrl+U at column 0 did nothing.

Why it is needed

Pressing Ctrl+U repeatedly should progressively clear lines upward, matching the behavior of kill_line_right (which joins the next line at end-of-line) and backspace (which joins lines at column 0). This is also consistent with how Claude Code handles the same keybinding. Without this fix, the user must manually press Backspace or move the cursor to join lines after clearing them with Ctrl+U.

Reviewer Test Plan

How to verify

  1. Type multi-line input in the prompt box (e.g. line1, Enter, line2, Enter, line3)
  2. Press Ctrl+U — should clear line3 (text to the left of cursor on current line)
  3. Press Ctrl+U again (cursor is now at column 0 of the cleared line) — should join the empty line with line2, resulting in line1, Enter, line2
  4. Press Ctrl+U again — should join line2 with line1, resulting in line1line2

Also run the unit tests:

cd packages/cli && npx vitest run src/ui/components/shared/text-buffer.test.ts

All 157 tests should pass (4 new tests added for kill_line_left).

Evidence (Before & After)

Before: Ctrl+U at column 0 does nothing — the line is not joined with the previous line.

After: Ctrl+U at column 0 joins the current line with the previous line, mirroring kill_line_right and backspace behavior.

_2026-06-12.104003.mp4

Tested on

OS Status
macOS tested
Windows not tested
Linux not tested

Risk & Scope

  • Main risk or tradeoff: Minimal — only affects the kill_line_left code path when cursorCol === 0 && cursorRow > 0. Existing behavior (cursorCol > 0 clears to left, cursorRow === 0 && cursorCol === 0 does nothing) is unchanged.
  • Not validated / out of scope: No changes to kill_line_right or other keybindings.
  • Breaking changes / migration notes: None.

Linked Issues

Fixes #4985

中文说明

改动内容

修复了 Ctrl+U (kill_line_left) 的行为:当光标位于行首 (column 0) 且不在第一行时,将当前行与上一行合并,光标移动到上一行末尾。之前按 Ctrl+U 在行首时什么都不做。

为什么需要这个改动

连续按 Ctrl+U 应该逐行向上清除,这与 kill_line_right (在行尾合并下一行) 和 backspace (在行首合并上一行) 的行为一致,也与 Claude Code 的行为一致。不修复此问题的话,用户在用 Ctrl+U 清除后还需手动按 Backspace 或移动光标来合并行。

Reviewer 测试计划

如何验证

  1. 在输入框中输入多行文本 (如 line1 Enter line2 Enter line3)
  2. 按 Ctrl+U — 应清除 line3 (光标左侧的文本)
  3. 再按一次 Ctrl+U (光标现在在空行的行首) — 应将空行与 line2 合并,结果为 line1 Enter line2
  4. 再按一次 Ctrl+U — 应将 line2 与 line1 合并,结果为 line1line2

也可运行单元测试:

cd packages/cli && npx vitest run src/ui/components/shared/text-buffer.test.ts

所有 157 个测试应通过 (新增 4 个 kill_line_left 测试)。

证据 (修改前 vs 修改后)

修改前: 行首按 Ctrl+U 无任何效果 — 当前行不会与上一行合并。

修改后: 行首按 Ctrl+U 将当前行与上一行合并,行为与 kill_line_right 和 backspace 一致。

测试环境

OS 状态
macOS 已测试
Windows 未测试
Linux 未测试

风险与范围

  • 主要风险: 极低 — 仅影响 kill_line_left 在 cursorCol === 0 && cursorRow > 0 时的代码路径。原有行为 (cursorCol > 0 清除左侧文本、cursorRow === 0 && cursorCol === 0 不操作) 不受影响。
  • 未验证/不涉及: 未修改 kill_line_right 或其他按键绑定。
  • 破坏性变更/迁移说明: 无。

关联 Issue

Fixes #4985

When cursor is at column 0 and not on the first line, kill_line_left
(Ctrl+U) now joins the current line with the previous line instead of
doing nothing. This mirrors the behavior of kill_line_right at end of
line and backspace at column 0, matching Claude Code's behavior.

Fixes QwenLM#4985
expect(state2).toHaveOnlyValidCharacters();
expect(state2.lines).toEqual(['line1line2line3']);
expect(state2.cursorRow).toBe(0);
expect(state2.cursorCol).toBe(5);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] Consider adding a test for undo after a join operation. The join is the most complex new code path (two lines merged, one spliced out, cursor repositioned), and none of the 4 new tests verify that undoing restores the original two-line state with correct cursorRow, cursorCol, and preferredCol. Something like:

it('should undo a join operation', () => {
  const stateWithText: TextBufferState = {
    ...initialState,
    lines: ['hello', 'world'],
    cursorRow: 1,
    cursorCol: 0,
  };
  const action: TextBufferAction = { type: 'kill_line_left' };
  const joined = textBufferReducer(stateWithText, action);
  expect(joined.lines).toEqual(['helloworld']);

  const undone = textBufferReducer(joined, { type: 'undo' });
  expect(undone.lines).toEqual(['hello', 'world']);
  expect(undone.cursorRow).toBe(1);
  expect(undone.cursorCol).toBe(0);
});

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! Added the undo test in af3a6c6 — verifies that undo after a join restores the original two-line state with correct cursorRow and cursorCol. All 158 tests pass.

Add test verifying that undo after a kill_line_left join restores
the original two-line state with correct cursorRow, cursorCol, and
preferredCol.

Co-authored-by: qwen-code-ci-bot

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found. LGTM! ✅ — qwen3.7-max via Qwen Code /review

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused fix and follow-up test update. I reviewed the latest head (af3a6c6) and verified the targeted text-buffer test passes; the change matches the existing line-join behavior and CI is green.

@yiliang114
yiliang114 merged commit b794d64 into QwenLM:main Jun 12, 2026
33 checks passed
doudouOUC pushed a commit that referenced this pull request Jun 15, 2026
* fix(cli): join previous line when Ctrl+U pressed at column 0

When cursor is at column 0 and not on the first line, kill_line_left
(Ctrl+U) now joins the current line with the previous line instead of
doing nothing. This mirrors the behavior of kill_line_right at end of
line and backspace at column 0, matching Claude Code's behavior.

Fixes #4985

* test(cli): add undo test for kill_line_left join operation

Add test verifying that undo after a kill_line_left join restores
the original two-line state with correct cursorRow, cursorCol, and
preferredCol.

Co-authored-by: qwen-code-ci-bot

---------

Co-authored-by: 俊良 <zzj542558@alibaba-inc.com>
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

Successfully merging this pull request may close these issues.

bug(cli): Ctrl+u can only clear the current line, not the previous line.

3 participants