Skip to content

Commit 57c7f6f

Browse files
gemini-cli-robotjacob314gemini-code-assist[bot]
authored
fix(patch): cherry-pick 8cae90f to release/v0.27.0-preview.7-pr-18108 [CONFLICTS] (#18230)
Co-authored-by: Jacob Richman <jacob314@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 93c2f0c commit 57c7f6f

2 files changed

Lines changed: 55 additions & 2 deletions

File tree

packages/cli/src/ui/components/shared/text-buffer.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,57 @@ describe('useTextBuffer', () => {
13841384
expect(state.visualCursor).toEqual([0, 1]);
13851385
});
13861386

1387+
it('move: up/down should work on wrapped lines (regression test)', () => {
1388+
// Line that wraps into two visual lines
1389+
// Viewport width 10. "0123456789ABCDE" (15 chars)
1390+
// Visual Line 0: "0123456789"
1391+
// Visual Line 1: "ABCDE"
1392+
const { result } = renderHook(() =>
1393+
useTextBuffer({
1394+
viewport: { width: 10, height: 5 },
1395+
isValidPath: () => false,
1396+
}),
1397+
);
1398+
1399+
act(() => {
1400+
result.current.setText('0123456789ABCDE');
1401+
});
1402+
1403+
// Cursor should be at the end: logical [0, 15], visual [1, 5]
1404+
expect(getBufferState(result).cursor).toEqual([0, 15]);
1405+
expect(getBufferState(result).visualCursor).toEqual([1, 5]);
1406+
1407+
// Press Up arrow - should move to first visual line
1408+
// This currently fails because handleInput returns false if cursorRow === 0
1409+
act(() => {
1410+
result.current.handleInput({
1411+
name: 'up',
1412+
shift: false,
1413+
alt: false,
1414+
ctrl: false,
1415+
cmd: false,
1416+
insertable: false,
1417+
sequence: '\x1b[A',
1418+
});
1419+
});
1420+
expect(getBufferState(result).visualCursor[0]).toBe(0);
1421+
1422+
// Press Down arrow - should move back to second visual line
1423+
// This would also fail if cursorRow is the last logical row
1424+
act(() => {
1425+
result.current.handleInput({
1426+
name: 'down',
1427+
shift: false,
1428+
alt: false,
1429+
ctrl: false,
1430+
cmd: false,
1431+
insertable: false,
1432+
sequence: '\x1b[B',
1433+
});
1434+
});
1435+
expect(getBufferState(result).visualCursor[0]).toBe(1);
1436+
});
1437+
13871438
it('moveToVisualPosition: should correctly handle wide characters (Chinese)', () => {
13881439
const { result } = renderHook(() =>
13891440
useTextBuffer({

packages/cli/src/ui/components/shared/text-buffer.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2905,12 +2905,12 @@ export function useTextBuffer({
29052905
return true;
29062906
}
29072907
if (keyMatchers[Command.MOVE_UP](key)) {
2908-
if (cursorRow === 0) return false;
2908+
if (visualCursor[0] === 0) return false;
29092909
move('up');
29102910
return true;
29112911
}
29122912
if (keyMatchers[Command.MOVE_DOWN](key)) {
2913-
if (cursorRow === lines.length - 1) return false;
2913+
if (visualCursor[0] === visualLines.length - 1) return false;
29142914
move('down');
29152915
return true;
29162916
}
@@ -2974,6 +2974,8 @@ export function useTextBuffer({
29742974
cursorCol,
29752975
lines,
29762976
singleLine,
2977+
visualCursor,
2978+
visualLines,
29772979
],
29782980
);
29792981

0 commit comments

Comments
 (0)